<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px" class="compact-form">
      <el-form-item label="客户姓名" prop="customerName">
        <el-input
          v-model="queryParams.customerName"
          placeholder="请输入客户姓名"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>

      <el-form-item label="联系电话" prop="contactPhone">
        <el-input
          v-model="queryParams.contactPhone"
          placeholder="请输入联系电话"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="身份证号码" prop="idCardNumber">
        <el-input
          v-model="queryParams.idCardNumber"
          placeholder="请输入身份证号码"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="案件负责人" prop="caseHandler">
        <el-select v-model="queryParams.caseHandler" placeholder="请选择案件负责人" clearable>
          <el-option
            v-for="item in userOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="经办人" prop="handlerUser">
        <el-select v-model="queryParams.handlerUser" placeholder="请选择经办人" clearable>
          <el-option
            v-for="item in userOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="委托机构" prop="entrustingInstitution">
        <el-select v-model="queryParams.entrustingInstitution" placeholder="请选择委托机构" clearable>
          <el-option
            v-for="dict in dict.type.wtjg"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="债务类型" prop="debtType">
        <el-select v-model="queryParams.debtType" placeholder="请选择债务类型" clearable>
          <el-option
            v-for="dict in dict.type.zwlx"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="诉讼/调解案号" prop="litigationMediationCaseNumber">
        <el-input
          v-model="queryParams.litigationMediationCaseNumber"
          placeholder="请输入诉讼/调解案号"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="执行案号" prop="enforcementCaseNumber">
        <el-input
          v-model="queryParams.enforcementCaseNumber"
          placeholder="请输入执行案号"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="案件进度状态" prop="caseProgressStatus">
        <el-select v-model="queryParams.caseProgressStatus" placeholder="请选择案件进度状态" clearable>
          <el-option
            v-for="dict in dict.type.ajjdzt"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="compact-mb">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:cases:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['system:cases:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['system:cases:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['system:cases:export']"
        >导出</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="info"
          plain
          icon="el-icon-phone"
          size="mini"
          @click="handleQuickAddContact"
          v-hasPermi="['system:contactrecord:add']"
        >快速添加联系记录</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-popover
          placement="bottom"
          width="200"
          trigger="manual"
          :value="showColumnSettings"
        >
          <el-checkbox-group v-model="selectedColumns" @change="handleColumnChange">
            <el-checkbox v-for="col in columnOptions" :key="col.prop" :label="col.prop">
              {{ col.label }}
            </el-checkbox>
          </el-checkbox-group>
          <el-button
            slot="reference"
            type="info"
            plain
            icon="el-icon-s-operation"
            size="mini"
            @click="toggleColumnSettings"
          >显示设置</el-button>
        </el-popover>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table
      v-loading="loading"
      :data="casesList"
      @selection-change="handleSelectionChange"
      :header-cell-style="{ background: '#f8f8f9', color: '#606266', padding: '5px 0' }"
      :cell-style="{ padding: '6px 0' }"
      border
      stripe
      size="mini"
      highlight-current-row
      height="calc(100vh - 120px)"
    >
      <el-table-column type="selection" width="35" align="center" />
      <el-table-column label="客户编号" min-width="70" align="center" prop="caseId" v-if="columnVisible('caseId')" />
      <el-table-column label="客户姓名" min-width="70" align="center" prop="customerName" v-if="columnVisible('customerName')" />
      <el-table-column label="联系电话" min-width="70" align="center" prop="contactPhone" v-if="columnVisible('contactPhone')" />
      <el-table-column label="身份证号码" min-width="70" align="center" prop="idCardNumber" v-if="columnVisible('idCardNumber')" />
      <el-table-column label="案件负责人" min-width="70" align="center" prop="caseHandler" v-if="columnVisible('caseHandler')">
        <template slot-scope="scope">
          <span v-if="scope.row.caseHandler">{{ getUserLabel(scope.row.caseHandler) }}</span>
          <span v-else></span>
        </template>
      </el-table-column>
      <el-table-column label="经办人" min-width="70" align="center" prop="handlerUser" v-if="columnVisible('handlerUser')">
        <template slot-scope="scope">
          <span v-if="scope.row.handlerUser">{{ getUserLabel(scope.row.handlerUser) }}</span>
          <span v-else></span>
        </template>
      </el-table-column>
      <el-table-column label="委托机构" min-width="70" align="center" prop="entrustingInstitution" v-if="columnVisible('entrustingInstitution')">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.wtjg" :value="scope.row.entrustingInstitution"/>
        </template>
      </el-table-column>
      <el-table-column label="债务类型" min-width="70" align="center" prop="debtType" v-if="columnVisible('debtType')">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.zwlx" :value="scope.row.debtType"/>
        </template>
      </el-table-column>
      <!--
      <el-table-column label="诉讼/调解案号" min-width="80" align="center" prop="litigationMediationCaseNumber" v-if="columnVisible('litigationMediationCaseNumber')" />
       -->
      <!--
       <el-table-column label="执行案号" min-width="80" align="center" prop="enforcementCaseNumber" v-if="columnVisible('enforcementCaseNumber')" /> 
       -->
      
      <el-table-column label="案件进度状态" align="center" prop="caseProgressStatus" v-if="columnVisible('caseProgressStatus')">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.ajjdzt" :value="scope.row.caseProgressStatus"/>
        </template>
      </el-table-column>
      <el-table-column label="案件进度说明" align="center" prop="caseProgressDescription" v-if="columnVisible('caseProgressDescription')" />

      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)">
            <el-button size="mini" type="primary">
              操作<i class="el-icon-arrow-down el-icon--right"></i>
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="update">修改</el-dropdown-item>
              <el-dropdown-item command="delete">删除</el-dropdown-item>
              <el-dropdown-item command="contact">联系记录</el-dropdown-item>
              <el-dropdown-item command="returnToPool">退回公海</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="handlePagination"
      :page-sizes="[20, 50, 100, 200, 500, -1]"
      :page-size-options="[{label: '20条/页', value: 20}, {label: '50条/页', value: 50}, {label: '100条/页', value: 100}, {label: '200条/页', value: 200}, {label: '500条/页', value: 500}, {label: '全部', value: -1}]"
      :background="true"
    />

    <!-- 添加或修改客户信息对话框 -->
    <el-dialog 
      :title="title" 
      :visible.sync="open" 
      :fullscreen="false"
      :close-on-click-modal="false"
      :close-on-press-escape="true"
      :destroy-on-close="false"
      width="1200px"
      append-to-body
      class="adaptive-dialog horizontal-center"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="100px" class="scrollable-form">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="客户姓名" prop="customerName">
              <el-input v-model="form.customerName" placeholder="请输入客户姓名" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="联系电话" prop="contactPhone">
              <el-input v-model="form.contactPhone" placeholder="请输入联系电话" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="身份证号码" prop="idCardNumber">
              <el-input v-model="form.idCardNumber" placeholder="请输入身份证号码" />
            </el-form-item>
          </el-col>
        </el-row>

         <!-- 关联人信息 -->
        <el-row>
          <el-col :span="24">
            <div class="section-header-compact">
              <span>关联人信息</span>
            </div>
            <el-form-item label="">
              <div class="contact-persons-container-compact">
                <div class="contact-persons-list-compact">
                  <div v-for="(person, index) in contactPersons" :key="`person-${index}`" class="contact-person-item-compact">
                    <el-input v-model="person.name" placeholder="姓名" size="mini" class="contact-input-compact"></el-input>
                    <el-input v-model="person.phone" placeholder="电话" size="mini" class="contact-input-compact" @blur="validatePhone(person)"></el-input>
                    <el-input v-model="person.idCard" placeholder="身份证号" size="mini" class="contact-input-compact" @blur="validateIdCard(person)"></el-input>
                    <el-button type="text" icon="el-icon-delete" class="contact-delete-btn-compact" @click="removeContactPerson(index)"></el-button>
                  </div>
                  <div class="contact-add-btn-wrapper">
                    <el-button 
                      type="text" 
                      icon="el-icon-plus" 
                      class="add-contact-btn-compact"
                      @click="addContactPerson"
                      :disabled="contactPersons.length >= 5">
                      添加关联人
                    </el-button>
                  </div>
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="案件负责人" prop="caseHandler">
              <el-select
                v-model="form.caseHandler"
                placeholder="请选择案件负责人"
                style="width: 100%"
                clearable
              >
                <el-option
                  v-for="item in userOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="经办人" prop="handlerUser">
              <el-select
                v-model="form.handlerUser"
                placeholder="请选择经办人"
                style="width: 100%"
                filterable
                clearable
              >
                <el-option
                  v-for="item in userOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="委托机构" prop="entrustingInstitution">
              <el-select v-model="form.entrustingInstitution" placeholder="请选择委托机构" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.wtjg"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="债务类型" prop="debtType">
              <el-select v-model="form.debtType" placeholder="请选择债务类型" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.zwlx"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="诉讼/调解案号" prop="litigationMediationCaseNumber">
              <el-input v-model="form.litigationMediationCaseNumber" placeholder="请输入诉讼/调解案号" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="执行案号" prop="enforcementCaseNumber">
              <el-input v-model="form.enforcementCaseNumber" placeholder="请输入执行案号" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="案件进度状态" prop="caseProgressStatus">
              <el-select v-model="form.caseProgressStatus" placeholder="请选择案件进度状态" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.ajjdzt"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="公海类型" prop="poolType">
              <el-select v-model="form.poolType" placeholder="请选择公海类型" style="width: 100%" clearable>
                <el-option
                  v-for="dict in dict.type.pool_type"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="案件进度说明" prop="caseProgressDescription">
              <el-input v-model="form.caseProgressDescription" type="textarea" :rows="3" placeholder="请输入内容" />
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row>
          <el-col :span="24">
            <el-form-item label="客户介绍" prop="customerIntro">
              <el-input 
                v-model="form.customerIntro" 
                type="textarea" 
                :rows="4" 
                placeholder="请输入客户介绍、背景信息等详细内容"
                maxlength="500"
                show-word-limit
              />
            </el-form-item>
          </el-col>
        </el-row>
        
        
        
        <el-row>
          <el-col :span="24">
            <el-form-item label="文件" prop="fileInfo">
              <el-upload
                class="upload-demo"
                :action="upload.url"
                :headers="upload.headers"
                :on-success="handleUploadSuccess"
                :on-error="handleUploadError"
                :on-remove="handleFileRemove"
                :before-upload="handleBeforeUpload"
                :file-list="fileList"
                multiple>
                <el-button size="small" type="primary">点击上传</el-button>
                <div slot="tip" class="el-upload__tip">文件大小不超过500MB</div>
              </el-upload>
              <div v-if="form.fileInfo" class="file-grid-container">
                <div v-for="(file, index) in parsedFileList" :key="index" class="file-grid-item">
                  <div class="file-icon">
                    <i :class="getFileIcon(file.name)"></i>
                  </div>
                  <div class="file-info">
                    <div class="file-name-ellipsis">{{ file.name }}</div>
                  </div>
                  <div class="file-actions">
                    <el-button
                      type="text"
                      size="mini"
                      icon="el-icon-download"
                      @click="handleDownload(file)"
                    ></el-button>
                    <el-button
                      type="text"
                      size="mini"
                      icon="el-icon-delete"
                      @click="handleFileDelete(index)"
                    ></el-button>
                  </div>
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="medium" @click="submitForm" icon="el-icon-check">确 定</el-button>
        <el-button size="medium" @click="cancel" icon="el-icon-close">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 客户联系记录对话框 -->
    <el-dialog :title="contactDialogTitle" :visible.sync="contactOpen" width="1000px" append-to-body>
      <div class="contact-record-container">
        <!-- 联系记录列表 -->
        <div class="contact-record-list">
          <el-button
            type="primary"
            icon="el-icon-plus"
            size="mini"
            @click="handleAddContact"
          >新增联系记录</el-button>

          <el-button
            type="info"
            icon="el-icon-refresh"
            size="mini"
            @click="getContactRecordList"
            style="margin-bottom: 10px; margin-left: 10px;"
          >刷新列表</el-button>

          <el-table v-loading="contactLoading" :data="contactList" border style="width: 100%">
            <el-table-column label="联系方式" align="center" prop="contactType" width="100">
              <template slot-scope="scope">
                <dict-tag :options="dict.type.contact_type" :value="scope.row.contactType"/>
              </template>
            </el-table-column>
            <el-table-column label="联系人" align="center" prop="contactPerson" width="120" />
            <el-table-column label="联系时间" align="center" prop="contactTime" width="150">
              <template slot-scope="scope">
                <span>{{ parseTime(scope.row.contactTime) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="联系结果" align="center" prop="contactResult" width="100">
              <template slot-scope="scope">
                <dict-tag :options="dict.type.contact_result" :value="scope.row.contactResult"/>
              </template>
            </el-table-column>
            <el-table-column label="联系内容" align="center" prop="contactContent" />
            <el-table-column label="下次联系时间" align="center" prop="nextContactTime" width="150">
              <template slot-scope="scope">
                <span>{{ parseTime(scope.row.nextContactTime) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="附件" align="center" width="120">
              <template slot-scope="scope">
                <div v-if="scope.row.fileInfo">
                  <el-popover
                    placement="top"
                    width="200"
                    trigger="hover">
                    <div>
                      <div v-for="(file, index) in parseFileInfo(scope.row.fileInfo)" :key="index" class="file-item">
                        <span class="file-name">{{ file.name }}</span>
                        <div class="file-actions">
                          <el-button type="text" size="mini" @click="handlePreviewFile(file)">预览</el-button>
                          <el-button type="text" size="mini" @click="handleDownload(file)">下载</el-button>
                        </div>
                      </div>
                    </div>
                    <el-button slot="reference" type="text" size="mini">查看文件</el-button>
                  </el-popover>
                </div>
                <span v-else>无附件</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="150">
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-edit"
                  @click="handleEditContact(scope.row)"
                  v-hasPermi="['system:contactrecord:edit']"
                >编辑</el-button>
                <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-delete"
                  @click="handleDeleteContact(scope.row)"
                  v-hasPermi="['system:contactrecord:remove']"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </el-dialog>

    <!-- 新增/编辑联系记录对话框 -->
    <el-dialog :title="contactFormTitle" :visible.sync="contactFormOpen" width="600px" append-to-body @opened="logContactDialogData">
      <el-form ref="contactForm" :model="contactForm" :rules="contactRules" label-width="100px">
        <el-form-item label="联系方式" prop="contactType">
          <el-select v-model="contactForm.contactType" placeholder="请选择联系方式" style="width: 100%">
            <el-option
              v-for="dict in dict.type.contact_type"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系人" prop="contactPerson">
          <el-input v-model="contactForm.contactPerson" placeholder="请输入联系人" />
        </el-form-item>
        <el-form-item label="联系时间" prop="contactTime">
          <el-date-picker
            v-model="contactForm.contactTime"
            type="datetime"
            placeholder="选择联系时间"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
            format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="联系结果" prop="contactResult">
          <el-select v-model="contactForm.contactResult" placeholder="请选择联系结果" style="width: 100%">
            <el-option
              v-for="dict in dict.type.contact_result"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系内容" prop="contactContent">
          <el-input
            v-model="contactForm.contactContent"
            type="textarea"
            :rows="3"
            placeholder="请输入联系内容"
          />
        </el-form-item>
        <el-form-item label="下次联系时间" prop="nextContactTime">
          <el-date-picker
            v-model="contactForm.nextContactTime"
            type="datetime"
            placeholder="选择下次联系时间"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
            format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="下次计划" prop="nextContactPlan">
          <el-input
            v-model="contactForm.nextContactPlan"
            type="textarea"
            :rows="2"
            placeholder="请输入下次联系计划"
          />
        </el-form-item>
        
        <!-- 添加文件上传组件 -->
        <el-form-item label="附件" prop="fileInfo">
          <el-upload
            class="upload-demo"
            :action="upload.url"
            :headers="upload.headers"
            :on-success="handleContactUploadSuccess"
            :on-error="handleQuickUploadError"
            :on-remove="handleContactFileRemove"
            :before-upload="handleBeforeUpload"
            :file-list="contactFileList"
            multiple>
            <el-button size="small" type="primary" icon="el-icon-upload2">上传文件</el-button>
            <div slot="tip" class="el-upload__tip">支持各种文档、图片等格式，文件大小不超过50MB</div>
          </el-upload>
          
          <!-- 显示已上传的文件列表 -->
          <div v-if="contactForm.fileInfo" class="existing-files">
            <div v-for="(file, index) in contactParsedFileList" :key="index" class="file-item">
              <span class="file-name">{{ file.name }}</span>
              <div class="file-actions">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-view"
                  @click="handlePreviewFile(file)"
                >预览</el-button>
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-download"
                  @click="handleDownload(file)"
                >下载</el-button>
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-delete"
                  @click="handleContactFileDelete(index)"
                >删除</el-button>
              </div>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitContactForm">确 定</el-button>
        <el-button @click="cancelContact">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 快速添加联系记录对话框 -->
    <el-dialog title="快速添加联系记录" :visible.sync="quickContactOpen" width="600px" append-to-body @opened="logQuickContactDialogData">
      <el-form ref="quickContactForm" :model="quickContactForm" :rules="quickContactRules" label-width="100px">
        <el-form-item label="选择客户" prop="caseId">
          <el-select
            v-model="quickContactForm.caseId"
            filterable
            placeholder="请选择客户"
            style="width: 100%"
            @change="handleCustomerChange"
          >
            <el-option
              v-for="item in customerOptions"
              :key="item.caseId"
              :label="item.customerName + ' (' + item.contactPhone + ')'"
              :value="item.caseId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系方式" prop="contactType">
          <el-select v-model="quickContactForm.contactType" placeholder="请选择联系方式" style="width: 100%">
            <el-option
              v-for="dict in dict.type.contact_type"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系人" prop="contactPerson">
          <el-input v-model="quickContactForm.contactPerson" placeholder="请输入联系人" />
        </el-form-item>
        <el-form-item label="联系结果" prop="contactResult">
          <el-select v-model="quickContactForm.contactResult" placeholder="请选择联系结果" style="width: 100%">
            <el-option
              v-for="dict in dict.type.contact_result"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="联系内容" prop="contactContent">
          <el-input
            v-model="quickContactForm.contactContent"
            type="textarea"
            :rows="3"
            placeholder="请输入联系内容"
          />
        </el-form-item>
        <el-form-item label="下次联系时间" prop="nextContactTime">
          <el-date-picker
            v-model="quickContactForm.nextContactTime"
            type="datetime"
            placeholder="选择下次联系时间"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
            format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
        </el-form-item>
        <el-form-item label="下次计划" prop="nextContactPlan">
          <el-input
            v-model="quickContactForm.nextContactPlan"
            type="textarea"
            :rows="2"
            placeholder="请输入下次联系计划"
          />
        </el-form-item>
        
        <!-- 添加文件上传组件 -->
        <el-form-item label="附件" prop="fileInfo">
          <el-upload
            class="upload-demo"
            :action="upload.url"
            :headers="upload.headers"
            :on-success="handleQuickUploadSuccess"
            :on-error="handleQuickUploadError"
            :on-remove="handleQuickFileRemove"
            :before-upload="handleBeforeUpload"
            :file-list="quickFileList"
            multiple>
            <el-button size="small" type="primary" icon="el-icon-upload2">上传文件</el-button>
            <div slot="tip" class="el-upload__tip">支持各种文档、图片等格式，文件大小不超过50MB</div>
          </el-upload>
          
          <!-- 显示已上传的文件列表 -->
          <div v-if="quickContactForm.fileInfo" class="existing-files">
            <div v-for="(file, index) in quickParsedFileList" :key="index" class="file-item">
              <span class="file-name">{{ file.name }}</span>
              <div class="file-actions">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-view"
                  @click="handlePreviewFile(file)"
                >预览</el-button>
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-download"
                  @click="handleDownload(file)"
                >下载</el-button>
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-delete"
                  @click="handleQuickFileDelete(index)"
                >删除</el-button>
              </div>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitQuickContactForm">确 定</el-button>
        <el-button @click="cancelQuickContact">取 消</el-button>
      </div>
    </el-dialog>
    
    <!-- 文件预览对话框 -->
    <el-dialog title="文件预览" :visible.sync="filePreviewVisible" width="80%" append-to-body class="preview-dialog" :before-close="handleClosePreview">
      <div class="preview-container" v-loading="previewLoading">
        <!-- 图片预览 -->
        <div v-if="isImageFile" class="image-preview-wrapper">
          <img v-if="!imageLoadError" :src="previewUrl" class="preview-image" alt="预览图片" @error="handleImageError">
          <div v-if="imageLoadError" class="image-error">
            <i class="el-icon-picture-outline"></i>
            <p>图片加载失败，请尝试下载后查看</p>
            <el-button type="primary" size="medium" @click="downloadPreviewFile">
              <i class="el-icon-download"></i> 下载图片
            </el-button>
          </div>
          <div v-if="!imageLoadError" class="image-toolbar">
            <el-button-group>
              <el-button type="primary" size="small" @click="downloadPreviewFile">
                <i class="el-icon-download"></i> 下载
              </el-button>
            </el-button-group>
          </div>
        </div>
        <!-- PDF预览 -->
        <div v-else-if="isPdfFile" class="pdf-preview-wrapper">
          <iframe v-if="!pdfLoadError" :src="previewUrl" class="preview-iframe" @load="handleIframeLoad" @error="handleIframeError"></iframe>
          <div v-if="pdfLoadError" class="pdf-error">
            <i class="el-icon-document"></i>
            <p>PDF文件加载失败，请尝试下载后查看</p>
            <el-button type="primary" size="medium" @click="downloadPreviewFile">
              <i class="el-icon-download"></i> 下载PDF
            </el-button>
          </div>
        </div>
        <!-- 其他文件类型 -->
        <div v-else class="no-preview">
          <i class="el-icon-document"></i>
          <p>无法预览当前文件类型，请下载后查看</p>
          <el-button type="primary" @click="downloadPreviewFile">下载文件</el-button>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="filePreviewVisible = false">关闭</el-button>
        <el-button type="primary" @click="downloadPreviewFile">下载文件</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listBankCustomerCases, getBankCustomerCases, delBankCustomerCases, addBankCustomerCases, updateBankCustomerCases, exportBankCustomerCases, updateCasesPool, updateContactPersons, deleteContactPerson } from "@/api/system/cases";
import { getToken } from "@/utils/auth";
import { listUser } from "@/api/system/user";
import { listContactRecord, getContactRecord, addContactRecord, updateContactRecord, delContactRecord, listContactRecordByCaseId } from "@/api/system/contactrecord";
import request from '@/utils/request'

export default {
  name: "Cases",
  dicts: ['ajjdzt', 'ajfzr', 'wtjg', 'zwlx', 'pool_type', 'contact_type', 'contact_result'],
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: false,
      // 总条数
      total: 0,
      // 客户信息表格数据
      casesList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        customerName: null,
        contactPhone: null,
        idCardNumber: null,
        caseHandler: null,
        handlerUser: null,
        entrustingInstitution: null,
        debtType: null,
        litigationMediationCaseNumber: null,
        enforcementCaseNumber: null,
        caseProgressStatus: null,
        caseProgressDescription: null,
        fileInfo: null,
        poolType: null,
        handlerUser2: null,
        isVisible: true // 默认只显示可见的客户
      },
      // 表单参数
      form: {
        caseId: null,
        customerName: null,
        contactPhone: null,
        idCardNumber: null,
        caseHandler: null,
        handlerUser: null,
        entrustingInstitution: null,
        debtType: null,
        litigationMediationCaseNumber: null,
        enforcementCaseNumber: null,
        caseProgressStatus: null,
        caseProgressDescription: null,
        fileInfo: null,
        poolType: null,
        poolEntryTime: null,
        customerIntro: null, // 客户介绍
        isVisible: true // 默认可见
      },
      // 表单校验
      rules: {
        customerName: [
          { required: true, message: "客户姓名不能为空", trigger: "blur" }
        ],
        poolType: [
          { required: false, trigger: "change" }
        ],
        contactPhone: [
          { pattern: /^1[3-9]\d{9}$/, message: "请输入正确的手机号码", trigger: "blur" }
        ],
        idCardNumber: [
          { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: "请输入正确的身份证号码", trigger: "blur" }
        ]
      },
      // 上传参数
      upload: {
        // 上传地址
        url: process.env.VUE_APP_BASE_API + "/system/cases/upload",
        // 请求头部
        headers: { Authorization: "Bearer " + getToken() }
      },
      // 文件列表
      fileList: [],
      parsedFileList: [], // 用于存储已解析的文件列表
      // 列显示配置
      columnOptions: [
        { label: '客户编号', prop: 'caseId' },
        { label: '客户姓名', prop: 'customerName' },
        { label: '联系电话', prop: 'contactPhone' },
        { label: '身份证号码', prop: 'idCardNumber' },
        { label: '案件负责人', prop: 'caseHandler' },
        { label: '经办人', prop: 'handlerUser' },
        { label: '委托机构', prop: 'entrustingInstitution' },
        { label: '债务类型', prop: 'debtType' },
        { label: '诉讼/调解案号', prop: 'litigationMediationCaseNumber' },
        { label: '执行案号', prop: 'enforcementCaseNumber' },
        { label: '案件进度状态', prop: 'caseProgressStatus' },
        { label: '案件进度说明', prop: 'caseProgressDescription' },
      ],
      selectedColumns: ['caseId', 'customerName', 'contactPhone', 'idCardNumber', 'caseHandler', 'handlerUser', 'entrustingInstitution',
        'debtType', 'litigationMediationCaseNumber', 'enforcementCaseNumber', 'caseProgressStatus', 'caseProgressDescription', 'fileInfo'],
      // 用户列表数据
      userOptions: [],
      lastMinuteTimestamp: '', // 记录最后一次生成编号的分钟时间戳
      currentMinuteCount: 0,   // 记录当前分钟内的客户计数

      // 联系记录相关
      contactDialogTitle: "",
      contactOpen: false,
      contactLoading: false,
      contactList: [],
      currentCaseId: null,
      currentCustomerName: "",

      // 联系记录表单相关
      contactFormTitle: "",
      contactFormOpen: false,
      contactForm: {
        recordId: null,
        caseId: null,
        contactType: "1", // 默认电话
        contactPerson: "",
        contactResult: "",
        contactTime: null,
        contactContent: "",
        nextContactTime: null,
        nextContactPlan: "",
        fileInfo: null  // 添加文件信息字段
      },
      contactRules: {
        contactType: [
          { required: true, message: "联系方式不能为空", trigger: "change" }
        ],
        contactPerson: [
          { required: true, message: "联系人不能为空", trigger: "blur" }
        ],
        contactResult: [
          { required: true, message: "联系结果不能为空", trigger: "change" }
        ],
        contactTime: [
          { required: true, message: "联系时间不能为空", trigger: "blur" }
        ],
        contactContent: [
          { required: true, message: "联系内容不能为空", trigger: "blur" }
        ]
      },

      // 快速添加联系记录相关
      quickContactOpen: false,
      customerOptions: [],
      quickContactForm: {
        caseId: null,
        contactType: "1", // 默认电话
        contactPerson: "",
        contactResult: "",
        contactTime: null,
        contactContent: "",
        nextContactTime: null,
        nextContactPlan: "",
        fileInfo: null // 添加文件信息字段
      },
      quickContactRules: {
        caseId: [
          { required: true, message: "请选择客户", trigger: "change" }
        ],
        contactType: [
          { required: true, message: "联系方式不能为空", trigger: "change" }
        ],
        contactPerson: [
          { required: true, message: "联系人不能为空", trigger: "blur" }
        ],
        contactResult: [
          { required: true, message: "联系结果不能为空", trigger: "change" }
        ],
        contactContent: [
          { required: true, message: "联系内容不能为空", trigger: "blur" }
        ]
      },
      
      // 退回公海相关
      returnToPoolDialogVisible: false,
      currentCaseToReturn: null,
      returnToPoolForm: {
        poolType: ""
      },
      returnToPoolRules: {
        poolType: [
          { required: true, message: "请选择公海池类型", trigger: "change" }
        ]
      },
      submitLoading: false,
      quickFileList: [],
      quickParsedFileList: [],
      // 文件预览相关
      filePreviewVisible: false,
      previewUrl: '',
      previewLoading: false,
      isImageFile: false,
      isPdfFile: false,
      currentPreviewFile: null,
      contactFileList: [],
      contactParsedFileList: [],
      imageLoadError: false,
      pdfLoadError: false,
      backupPreviewUrl: null,
      showColumnSettings: false,
      // 关联人数据
      contactPersons: [{ name: '', phone: '', phoneError: false, idCard: '', idCardError: false }],
      contactPersonsKey: 0, // 添加key用于强制更新表格
    };
  },
  created() {
    // 加载字典数据、列表和用户信息
    this.getList();
    this.getUsers();
  },
  methods: {
    /** 查询客户信息列表 */
    getList() {
      this.loading = true;

      // 处理"全部"选项的情况
      const params = {...this.queryParams};
      if (params.pageSize === -1) {
        params.pageSize = 10000; // 设置一个足够大的数字以获取所有记录
      }
      
      // 设置视图标识 - 客户信息页面
      params.viewMode = 'customer';
      
      // 确保isVisible参数存在，默认只显示可见的客户
      params.isVisible = params.isVisible !== undefined ? params.isVisible : true;
      
      // 发送查询参数到后端

      listBankCustomerCases(params).then(response => {
        if (response.code === 200) {
          // 直接使用服务器返回的数据，不做任何过滤
          this.casesList = response.rows || [];
          this.total = response.total || 0;
          
          // 如果有案件负责人筛选条件，确保只显示该负责人的记录
          if (params.caseHandler && params.caseHandler.trim() !== '') {
            const beforeFilter = this.casesList.length;
            this.casesList = this.casesList.filter(item => item.caseHandler === params.caseHandler);
            this.total = this.casesList.length;
          }
          
          // 如果列表为空，显示提示消息
          if (this.casesList.length === 0) {
            this.$message.info('没有找到符合条件的客户信息');
          }
        } else {
          this.$modal.msgError(response.msg || '获取数据失败');
          this.casesList = [];
          this.total = 0;
        }
        this.loading = false;
      }).catch(error => {
        console.error('获取数据失败:', error);
        this.$modal.msgError('获取数据失败，请检查网络连接');
        this.loading = false;
        this.casesList = [];
        this.total = 0;
      });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
          // 表单重置
    reset() {
      this.form = {
        caseId: null,
        customerName: null,
        contactPhone: null,
        idCardNumber: null,
        caseHandler: null,
        handlerUser: null,
        entrustingInstitution: null,
        debtType: null,
        litigationMediationCaseNumber: null,
        enforcementCaseNumber: null,
        caseProgressStatus: null,
        caseProgressDescription: null,
        fileInfo: null,
        poolType: null,
        poolEntryTime: null,
        customerIntro: null, // 客户介绍
        isVisible: true // 默认可见
      };
      // 清空文件列表
      this.fileList = [];
      this.parsedFileList = [];

      // 重置关联人信息
      this.contactPersons = [];
      this.contactPersonsKey += 1;

      // 延迟一帧添加默认空白关联人
      this.$nextTick(() => {
        // 添加一个空白关联人
        this.contactPersons = [{ name: '', phone: '', phoneError: false, idCard: '', idCardError: false }];
        this.contactPersonsKey += 1;
        this.$forceUpdate();
        
        // 重置表单验证
        if (this.$refs.form) {
          this.$refs.form.resetFields();
          // 手动设置案件负责人和经办人为 null
          this.form.caseHandler = null;
          this.form.handlerUser = null;
        }
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      
      // 提示用户正在过滤数据
      if (this.queryParams.caseHandler) {
        this.$message.success(`正在搜索案件负责人为"${this.getUserLabel(this.queryParams.caseHandler)}"的客户数据`);
      }
      
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      // 保留isVisible为true，确保只显示可见的客户
      this.queryParams.isVisible = true;
      this.queryParams.pageNum = 1;
      this.queryParams.pageSize = 20;
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.caseId)
      this.single = selection.length!==1
      this.multiple = !selection.length
    },
    /** 新增按钮操作 */
    handleAdd() {
      // 先创建一个全新的表单对象，确保所有字段都是初始值
      this.form = {
        caseId: null,
        customerName: null,
        contactPhone: null,
        idCardNumber: null,
        caseHandler: null,
        handlerUser: null,
        entrustingInstitution: null,
        debtType: null,
        litigationMediationCaseNumber: null,
        enforcementCaseNumber: null,
        caseProgressStatus: null,
        caseProgressDescription: null,
        poolType: null,
        customerIntro: null, // 客户介绍
        isVisible: true
      };
      
      // 重置关联人信息
      this.contactPersons = [{ name: '', phone: '', phoneError: false, idCard: '', idCardError: false }];
      
      // 清空文件列表
      this.fileList = [];
      this.parsedFileList = [];
      
      // 先打开对话框
      this.open = true;
      this.title = "添加客户信息";
      
      // 确保表单完全重置，延迟执行以确保DOM已更新
      this.$nextTick(() => {
        if (this.$refs.form) {
          // 重置表单验证状态
          this.$refs.form.resetFields();
          
          // 再次确保所有字段为null，防止显示上次的值
          this.form.customerName = null;
          this.form.contactPhone = null;
          this.form.idCardNumber = null;
          this.form.caseHandler = null;
          this.form.handlerUser = null;
          this.form.entrustingInstitution = null;
          this.form.debtType = null;
          this.form.litigationMediationCaseNumber = null;
          this.form.enforcementCaseNumber = null;
          this.form.caseProgressStatus = null;
          this.form.caseProgressDescription = null;
          this.form.poolType = null;
          
          // 打印日志，确认表单状态
          // 表单已重置完成
        }
      });
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      
      const caseId = row.caseId || this.ids;
      
      getBankCustomerCases(caseId).then(response => {
        if (response.code === 200) {
          const data = response.data;
          
          this.form = {
            ...data,
            poolType: data.poolType || null
          };

          // 解析关联人信息
          if (data.contactPersonName && data.contactPersonPhone) {
            try {
              // 使用parseContactPersons方法解析
              this.contactPersons = this.parseContactPersons(data.contactPersonName, data.contactPersonPhone, data.contactPersonIdCard);
              
              // 如果解析结果为空，添加一个空的关联人
              if (!this.contactPersons || this.contactPersons.length === 0) {
                this.contactPersons = [{ name: '', phone: '', idCard: '', phoneError: false, idCardError: false }];
              }
            } catch (e) {
              this.contactPersons = [{ name: '', phone: '', idCard: '', phoneError: false, idCardError: false }];
            }
          } else {
            // 如果没有关联人信息，初始化为一个空的关联人
            this.contactPersons = [{ name: '', phone: '', idCard: '', phoneError: false, idCardError: false }];
          }

          this.updateParsedFileList();
          this.open = true;
          this.title = "修改客户信息";
        } else {
          this.$modal.msgError(response.msg || "获取客户信息失败");
        }
      }).catch(error => {
        this.$modal.msgError("获取客户信息失败，请重试");
      });
    },
    /** 生成客户编号 */
    generateCustomerId() {
      const now = new Date();
      const currentMinute = now.getFullYear().toString().substr(-2) +
        String(now.getMonth() + 1).padStart(2, '0') +
        String(now.getDate()).padStart(2, '0') +
        String(now.getHours()).padStart(2, '0') +
        String(now.getMinutes()).padStart(2, '0');

      // 如果是新的一分钟，重置计数器
      if (currentMinute !== this.lastMinuteTimestamp) {
        this.lastMinuteTimestamp = currentMinute;
        this.currentMinuteCount = 1;
      } else {
        // 同一分钟内，计数器加1
        this.currentMinuteCount++;
      }

      // 生成两位序号
      const sequenceNumber = String(this.currentMinuteCount).padStart(2, '0');
      return currentMinute + sequenceNumber;
    },
    /** 检查关联人数据有效性 */
    validateContactPersons() {
      // 如果没有关联人数据，直接返回true
      if (!this.contactPersons || this.contactPersons.length === 0) {
        return true;
      }
      
      try {
        // 检查长度限制
        let hasError = false;
        this.contactPersons.forEach((person, index) => {
          // 验证手机号
          if (person.phone && person.phone.trim() !== '') {
            if (person.phone.length > 11) {
              this.$message.warning(`第${index + 1}个关联人的手机号长度不能超过11位`);
              hasError = true;
              person.phoneError = true; // 设置错误标记
            } else {
              person.phoneError = false; // 清除错误标记
            }
          } else {
            person.phoneError = false; // 清除错误标记
          }
          
          // 验证身份证号码
          if (person.idCard && person.idCard.trim() !== '') {
            if (person.idCard.length > 18) {
              this.$message.warning(`第${index + 1}个关联人的身份证号码长度不能超过18位`);
              hasError = true;
              person.idCardError = true; // 设置错误标记
            } else {
              person.idCardError = false; // 清除错误标记
            }
          } else {
            person.idCardError = false; // 清除错误标记
          }
        });
        
        // 检查是否有有效的关联人数据（至少有姓名或电话或身份证号码）
        const validContacts = this.contactPersons.filter(p => {
          const nameValid = p.name && p.name.trim() !== '';
          const phoneValid = p.phone && p.phone.trim() !== '';
          const idCardValid = p.idCard && p.idCard.trim() !== '';
          return nameValid || phoneValid || idCardValid;
        });
        
        // 记录日志
        console.log('验证关联人数据:', {
          total: this.contactPersons.length,
          valid: validContacts.length,
          hasError: hasError
        });
        
        return !hasError;
      } catch (e) {
        console.error('验证关联人信息失败:', e);
        this.$message.error('关联人信息格式错误：' + e.message);
        return false;
      }
    },
    
    /** 提交按钮 */
    submitForm() {
      // 先验证关联人信息
      const contactPersonValid = this.validateContactPersons();
      
      // 如果关联人信息有错误，不继续提交
      if (!contactPersonValid) {
        this.$message.error('请先修正关联人信息中的错误');
        return;
      }
      
      this.$refs["form"].validate(valid => {
        if (valid) {
          const now = new Date();
          const formattedDate = now.getFullYear() + '-' +
            String(now.getMonth() + 1).padStart(2, '0') + '-' +
            String(now.getDate()).padStart(2, '0') + ' ' +
            String(now.getHours()).padStart(2, '0') + ':' +
            String(now.getMinutes()).padStart(2, '0') + ':' +
            String(now.getSeconds()).padStart(2, '0');

          // 处理特殊字段
          const caseHandler = this.form.caseHandler || null;
          const handlerUser = this.form.handlerUser || null;
          const poolType = this.form.poolType || null;

          // 处理关联人信息
          const contactData = this.cleanContactPersonData();

          // 准备关联人字段的JSON字符串
          const contactPersonName = JSON.stringify(contactData.names || []);
          const contactPersonPhone = JSON.stringify(contactData.phones || []);
          const contactPersonIdCard = JSON.stringify(contactData.idCards || []);

          // 构建提交数据，确保关联人字段是字符串类型
          const submitData = {
            ...this.form,
            caseId: this.form.caseId || this.generateCustomerId(),
            poolType: poolType,
            poolEntryTime: poolType ? formattedDate : null,
            updateBy: this.$store.state.user.name,
            caseHandler: caseHandler,
            handlerUser: handlerUser,
            isVisible: true,
            contactPersonName: contactPersonName,
            contactPersonPhone: contactPersonPhone,
            contactPersonIdCard: contactPersonIdCard
          };
          
          // 添加提交状态跟踪
          this.submitLoading = true;

          if (this.form.caseId != null) {
            updateBankCustomerCases(submitData).then(response => {
              this.submitLoading = false;
              
              if (response.code === 200) {
                this.$modal.msgSuccess("修改成功");
                this.open = false;
                
                // 立即调用API保存关联人信息，确保关联人数据被正确保存
                const contactSubmitData = {
                  caseId: this.form.caseId,
                  contactPersonName: JSON.stringify(contactData.names || []),
                  contactPersonPhone: JSON.stringify(contactData.phones || []),
                  contactPersonIdCard: JSON.stringify(contactData.idCards || [])
                };
                
                // 调用API保存关联人信息
                updateContactPersons(contactSubmitData).finally(() => {
                  // 无论成功失败都刷新列表
                  this.getList();
                });
              } else {
                this.$modal.msgError(response.msg || "修改失败");
              }
            }).catch(error => {
              this.submitLoading = false;
              this.$modal.msgError("修改失败: " + (error.message || '未知错误'));
            });
          } else {
            addBankCustomerCases(submitData).then(response => {
              this.submitLoading = false;
              
              if (response.code === 200) {
                this.$modal.msgSuccess("新增成功");
                this.open = false;
                this.getList();
              } else {
                this.$modal.msgError(response.msg || "新增失败");
              }
            }).catch(error => {
              this.submitLoading = false;
              this.$modal.msgError("新增失败: " + (error.message || '未知错误'));
            });
          }
        } else {
          return false;
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const caseIds = row.caseId || this.ids;
      this.$modal.confirm('是否确认删除客户信息编号为"' + caseIds + '"的数据项？').then(function() {
        return delBankCustomerCases(caseIds);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/cases/export', {
        ...this.queryParams
      }, `cases_${new Date().getTime()}.xlsx`)
    },
    /** 文件上传成功处理 */
    handleUploadSuccess(response, file, fileList) {
      if (response.code === 200) {
        // 如果是新建客户
        if (!this.form.caseId) {
          // 如果已经有文件信息，追加新文件
          if (this.form.fileInfo) {
            this.form.fileInfo = this.form.fileInfo + ';' + response.data;
          } else {
            // 如果还没有文件信息，直接使用新文件
            this.form.fileInfo = response.data;
          }
        } else {
          // 如果是修改客户，追加新文件
          const currentFiles = this.form.fileInfo ? this.form.fileInfo.split(';') : [];
          currentFiles.push(response.data);
          this.form.fileInfo = currentFiles.join(';');
        }

        // 更新文件列表显示
        this.fileList = fileList;
        this.updateParsedFileList();
        this.$modal.msgSuccess(response.msg);
      } else {
        this.$modal.msgError(response.msg);
      }
    },
    /** 更新已解析的文件列表 */
    updateParsedFileList() {
      if (!this.form.fileInfo) {
        this.parsedFileList = [];
        return;
      }

      // 使用一个封装的工具函数来处理文件信息
      this.parsedFileList = this.parseFileInfoToArray(this.form.fileInfo);
      
      // 更新form中的fileInfo，确保没有重复项
      this.form.fileInfo = this.convertFileArrayToString(this.parsedFileList);
    },
    /** 文件删除处理 */
    handleFileDelete(index) {
      this.$modal.confirm('是否确认删除该文件？').then(() => {
        const files = this.form.fileInfo.split(';');
        files.splice(index, 1);
        this.form.fileInfo = files.join(';');
        this.updateParsedFileList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 文件移除处理 */
    handleFileRemove(file, fileList) {
      // 从parsedFileList中找到对应的文件信息
      const removedFile = this.parsedFileList.find(f => f.name === file.name);
      if (removedFile) {
        // 从fileInfo中移除该文件
        const files = this.form.fileInfo.split(';').filter(f => f !== removedFile.fullInfo);
        this.form.fileInfo = files.join(';');
        this.updateParsedFileList();
      }
      this.fileList = fileList;
    },
    /** 文件上传失败处理 */
    handleUploadError(error) {
      this.$modal.msgError("上传失败，请重试");
    },
    /** 文件上传前的处理 */
    handleBeforeUpload(file) {
      const isLt500M = file.size / 1024 / 1024 < 500;
      if (!isLt500M) {
        this.$modal.msgError('上传文件大小不能超过 500MB!');
        return false;
      }
      return true;
    },
    /** 获取原始文件名 */
    getOriginalFileName(fileInfo) {
      if (!fileInfo) return '';
      const parts = fileInfo.split('|');
      return parts[0] || '';
    },
    /** 获取存储路径 */
    getStoragePath(fileInfo) {
      if (!fileInfo) return '';
      const parts = fileInfo.split('|');
      return parts[1] || '';
    },
    /** 下载单个文件 */
    handleDownload(file) {
      const baseUrl = process.env.VUE_APP_BASE_API;
      const token = getToken();
      const url = baseUrl + "/system/cases/download-file?filePath=" + encodeURIComponent(file.path);

      const xhr = new XMLHttpRequest();
      xhr.open("GET", url, true);
      xhr.responseType = "blob";
      xhr.setRequestHeader("Authorization", "Bearer " + token);

      xhr.onload = () => {
        if (xhr.status === 200) {
          const blob = new Blob([xhr.response]);
          if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(blob, file.name);
          } else {
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement("a");
            link.href = url;
            link.setAttribute("download", file.name);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
          }
        } else {
          this.$modal.msgError("下载失败");
        }
      };

      xhr.onerror = () => {
        this.$modal.msgError("下载失败");
      };

      xhr.send();
    },
    // 判断列是否显示
    columnVisible(prop) {
      return this.selectedColumns.includes(prop);
    },
    // 处理列显示变化
    handleColumnChange(value) {
      this.selectedColumns = value;
      // 至少保留一列
      if (this.selectedColumns.length === 0) {
        this.$message.warning('至少需要显示一列');
        this.selectedColumns = ['customerName'];
      }
      
      // 延迟一会儿后自动关闭显示设置面板
      setTimeout(() => {
        this.showColumnSettings = false;
      }, 300);
    },
    /** 获取用户列表 */
    getUsers() {
      listUser({
        pageSize: 500, // 增加一次性获取的用户数量
        status: "0" // 获取所有正常状态的用户
      }).then(response => {
        if (response.code === 200) {
          this.userOptions = response.rows.map(item => ({
            value: item.userName,
            label: item.nickName
          }));
          console.log('获取用户数据成功，共加载用户数: ', this.userOptions.length);
        } else {
          console.error('获取用户数据失败:', response.msg);
        }
      }).catch(error => {
        console.error('获取用户列表失败:', error);
      });
    },
    /** 获取用户显示标签 */
    getUserLabel(userName) {
      if (!userName) return '';
      const user = this.userOptions.find(item => item.value === userName);
      return user ? user.label : userName;
    },
    /** 判断是否为JSON数组 */
    isJsonArray(str) {
      if (!str) return false;
      try {
        const obj = JSON.parse(str);
        return Array.isArray(obj);
      } catch (e) {
        return false;
      }
    },
    /** 解析关联人信息 */
    parseContactPersons(namesJson, phonesJson, idCardsJson) {
      try {
        // 检查是否为空数组字符串
        if (namesJson === '[]' && phonesJson === '[]' && (idCardsJson === '[]' || !idCardsJson)) {
          return [];
        }
        
        // 确保有默认值
        const namesStr = namesJson || '[]';
        const phonesStr = phonesJson || '[]';
        const idCardsStr = idCardsJson || '[]';
        
        // 尝试解析JSON
        let names = [], phones = [], idCards = [];
        
        try { names = JSON.parse(namesStr); } catch (e) { names = []; }
        try { phones = JSON.parse(phonesStr); } catch (e) { phones = []; }
        try { idCards = JSON.parse(idCardsStr); } catch (e) { idCards = []; }
        
        // 确保结果是数组
        if (!Array.isArray(names)) names = [];
        if (!Array.isArray(phones)) phones = [];
        if (!Array.isArray(idCards)) idCards = [];
        
        // 判断是否所有数组都为空
        if (names.length === 0 && phones.length === 0 && idCards.length === 0) {
          return [];
        }
        
        // 确保三个数组长度一致，取最大长度
        const maxLength = Math.max(names.length, phones.length, idCards.length);
        
        // 构建关联人数组
        const result = [];
        for (let i = 0; i < maxLength; i++) {
          const name = i < names.length ? names[i] : '';
          const phone = i < phones.length ? phones[i] : '';
          const idCard = i < idCards.length ? idCards[i] : '';
          
          // 只验证长度
          const phoneError = phone && phone.length > 11;
          const idCardError = idCard && idCard.length > 18;
          
          // 只添加有内容的关联人
          if (name || phone || idCard) {
            result.push({
              name: name || '',
              phone: phone || '',
              idCard: idCard || '',
              phoneError,
              idCardError
            });
          }
        }
        
        return result.length > 0 ? result : [];
      } catch (e) {
        return [];
      }
    },
    /**
     * 添加关联人
     */
    addContactPerson() {
      try {
        // 初始化关联人数组（如果需要）
        this.initContactPersonsArrayIfNeeded();
        
        // 检查是否达到最大数量
        if (this.isContactPersonsLimitReached()) {
          this.$message.warning('最多添加5个关联人');
          return;
        }
        
        // 使用工具方法更新数组
        this.updateContactPersonsArray(oldArray => {
          // 添加新的空关联人对象
          return [...oldArray, this.createEmptyContactPerson()];
        });
      } catch (error) {
        this.$message.error('添加关联人失败');
      }
    },
    
    /**
     * 初始化关联人数组（如果需要）
     */
    initContactPersonsArrayIfNeeded() {
      if (!this.contactPersons || !Array.isArray(this.contactPersons)) {
        this.contactPersons = [];
      }
    },
    
    /**
     * 检查是否已达到关联人数量上限
     * @returns {Boolean} 是否达到上限
     */
    isContactPersonsLimitReached() {
      return this.contactPersons.length >= 5;
    },
    
    /**
     * 创建空的关联人对象
     * @returns {Object} 空的关联人对象
     */
    createEmptyContactPerson() {
      return {
        name: '',
        phone: '',
        phoneError: false,
        idCard: '',
        idCardError: false
      };
    },
   
    /**
     * 清理关联人数据，用于表单提交前的处理
     * @returns {Object} 处理后的关联人数据对象
     */
    cleanContactPersonData() {
      // 使用空数据对象
      const emptyResult = this.createEmptyContactDataResult();
      
      // 如果contactPersons为null或空数组，直接返回空数据
      if (!this.contactPersons || this.contactPersons.length === 0) {
        return emptyResult;
      }
      
      try {
        // 深拷贝避免修改原始数据
        const contactList = this.deepCloneArray(this.contactPersons);
      
        // 过滤有效的联系人数据
        const validContacts = this.filterValidContactPersons(contactList);
      
        // 提取并返回处理后的数据
        return this.extractContactPersonFields(validContacts);
      } catch (error) {
        // 出错时返回空数组
        return emptyResult;
      }
    },
    
    /**
     * 创建空的关联人数据结果对象
     * @returns {Object} 空的结果对象
     */
    createEmptyContactDataResult() {
      return {
        names: [],
        phones: [],
        idCards: [],
        isEmpty: true
      };
    },
    
    /**
     * 深拷贝数组
     * @param {Array} array - 要复制的数组
     * @returns {Array} 深拷贝后的新数组
     */
    deepCloneArray(array) {
      return JSON.parse(JSON.stringify(array));
    },
    
    /**
     * 过滤有效的关联人数据
     * @param {Array} contactList - 关联人列表
     * @returns {Array} 有效的关联人列表
     */
    filterValidContactPersons(contactList) {
      return contactList.filter(p => {
        const hasName = p.name && p.name.trim() !== '';
        const hasPhone = p.phone && p.phone.trim() !== '';
        const hasIdCard = p.idCard && p.idCard.trim() !== '';
        return hasName || hasPhone || hasIdCard;
      });
    },
    
    /**
     * 从关联人列表中提取字段数据
     * @param {Array} validContacts - 有效的关联人列表
     * @returns {Object} 提取的字段数据
     */
    extractContactPersonFields(validContacts) {
      // 提取姓名、电话和身份证号码数组
      const names = validContacts.map(p => p.name ? p.name.trim() : '');
      const phones = validContacts.map(p => p.phone ? p.phone.trim() : '');
      const idCards = validContacts.map(p => p.idCard ? p.idCard.trim() : '');
      
      // 返回处理后的数据
      return {
        names,
        phones,
        idCards,
        isEmpty: names.length === 0
      };
    },
    
    /**
     * 处理联系记录按钮操作
     * @param {Object} row - 表格行数据
     */
    handleContactRecord(row) {
      // 设置当前客户信息
      this.setCurrentCustomer(row);
      
      // 加载联系记录数据
      this.loadContactRecords();
    },
    
    /**
     * 设置当前客户信息
     * @param {Object} customer - 客户信息
     */
    setCurrentCustomer(customer) {
      this.currentCaseId = customer.caseId;
      this.currentCustomerName = customer.customerName;
      this.contactDialogTitle = `${customer.customerName} 的联系记录`;
    },
    
    /**
     * 加载联系记录数据
     */
    loadContactRecords() {
      // 设置加载状态
      this.contactLoading = true;
      
      // 获取联系记录
      listContactRecordByCaseId(this.currentCaseId)
        .then(this.handleContactRecordsResponse)
        .catch(this.handleContactRecordsError);
    },
    
    /**
     * 处理联系记录响应
     * @param {Object} response - API响应
     */
    handleContactRecordsResponse(response) {
      this.contactLoading = false;
      this.contactOpen = true;
      
      if (response.code === 200) {
        this.contactList = response.data || [];
      } else {
        this.$modal.msgError('获取联系记录失败: ' + (response.msg || '未知错误'));
      }
    },
    
    /**
     * 处理联系记录错误
     */
    handleContactRecordsError() {
      this.contactLoading = false;
      this.contactOpen = true;
      
      if (process.env.NODE_ENV === 'development') {
        this.$modal.msgError('开发提示：联系记录API请求失败');
      }
    },
    /**
     * 获取联系记录列表(用于刷新按钮)
     */
    getContactRecordList() {
      if (!this.currentCaseId) {
        this.resetContactList();
        return;
      }

      // 重用已有的联系记录加载方法
      this.loadContactRecords();
    },
    
    /**
     * 重置联系记录列表
     */
    resetContactList() {
      this.contactList = [];
      this.contactLoading = false;
    },
    /** 新增联系记录按钮操作 */
    handleAddContact() {
      // 确保表单数据重置
      this.resetContactForm();
      this.setContactFormDefaults();
      this.contactFormTitle = "添加联系记录";
      this.contactFormOpen = true;
    },
    /** 设置联系记录表单默认值 */
    setContactFormDefaults() {
      // 设置默认值
      this.contactForm.caseId = this.currentCaseId;
      const now = new Date();
      this.contactForm.contactTime = this.parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}');
      this.contactForm.contactPerson = this.getUserInfo().userName || '';
    },
    /**
     * 修改联系记录按钮操作
     * @param {Object} row - 表格行数据
     */
    handleEditContact(row) {
      this.resetContactForm();
      this.loadContactRecordDetails(row.recordId);
    },
    
    /**
     * 加载联系记录详情
     * @param {Number|String} recordId - 记录ID
     */
    loadContactRecordDetails(recordId) {
      getContactRecord(recordId)
        .then(response => this.handleContactRecordDetailsResponse(response))
        .catch(() => this.$modal.msgError("获取联系记录失败，请重试"));
    },
    
    /**
     * 处理联系记录详情响应
     * @param {Object} response - API响应
     */
    handleContactRecordDetailsResponse(response) {
      if (response.code === 200) {
        // 设置表单数据
        this.contactForm = response.data;
        
        // 更新文件列表
        this.updateContactFileComponents();
        
        // 打开编辑对话框
        this.contactFormTitle = "修改联系记录";
        this.contactFormOpen = true;
      } else {
        this.$modal.msgError(response.msg || "获取联系记录失败");
      }
    },
    
    /**
     * 更新联系记录文件组件
     */
    updateContactFileComponents() {
      // 更新文件列表显示
      this.updateContactParsedFileList();
      
      // 更新上传组件的文件列表
      if (this.contactForm.fileInfo && this.contactParsedFileList.length > 0) {
        this.contactFileList = this.convertToUploadComponentFormat(this.contactParsedFileList);
      }
    },
    
    /**
     * 将文件信息转换为上传组件格式
     * @param {Array} files - 文件信息数组
     * @returns {Array} 上传组件格式的文件列表
     */
    convertToUploadComponentFormat(files) {
      return files.map(file => ({
        name: file.name,
        url: file.path
      }));
    },
    /** 删除联系记录操作 */
    handleDeleteContact(row) {
      this.$confirm('是否确认删除该联系记录?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return delContactRecord(row.recordId);
      }).then(() => {
        this.getContactRecordList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 提交联系记录表单 */
    submitContactForm() {
      console.log('开始提交联系记录表单');
      console.log('表单数据:', this.contactForm);
      console.log('当前用户权限:', this.$store.getters.permissions);

      this.$refs["contactForm"].validate(valid => {
        console.log('表单验证结果:', valid);
        if (valid) {
          // 创建表单数据的副本并格式化日期
          const formData = this.formatDateFields({...this.contactForm});
          console.log('格式化后的表单数据:', formData);
          
          // 确保文件信息包含在提交数据中
          if (this.contactForm.fileInfo) {
            formData.fileInfo = this.contactForm.fileInfo;
          }

          if (formData.recordId != null) {
            console.log('更新联系记录:', formData.recordId);
            updateContactRecord(formData).then(response => {
              console.log('更新联系记录响应:', response);
              if (response.code === 200) {
                this.$modal.msgSuccess("修改成功");
                this.contactFormOpen = false;
                // 刷新联系记录列表
                this.getContactRecordList();
              } else {
                console.error('更新联系记录失败:', response);
                this.$modal.msgError(response.msg || "修改失败");
              }
            }).catch(error => {
              console.error("修改联系记录失败:", error);
              this.$modal.msgError("修改失败，请重试");
            });
          } else {
            console.log('新增联系记录:', formData);
            addContactRecord(formData).then(response => {
              console.log('新增联系记录响应:', response);
              if (response.code === 200) {
                this.$modal.msgSuccess("新增成功");
                this.contactFormOpen = false;
                // 刷新联系记录列表
                this.getContactRecordList();
              } else {
                console.error('新增联系记录失败:', response);
                this.$modal.msgError(response.msg || "新增失败");
              }
            }).catch(error => {
              console.error("新增联系记录失败:", error);
              this.$modal.msgError("新增失败，请重试");
            });
          }
        } else {
          console.error('表单验证失败');
        }
      });
    },
    /** 取消联系记录表单 */
    cancelContact() {
      this.contactFormOpen = false;
      this.resetContactForm();
    },
    /** 重置联系记录表单 */
    resetContactForm() {
      const now = new Date();

      // 设置表单初始值
      this.contactForm = {
        recordId: null,
        caseId: this.currentCaseId,
        contactType: "1", // 默认设置为"电话"
        contactPerson: this.getUserInfo().userName || '',
        contactResult: "", // 不设置默认结果
        contactTime: this.parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}'),
        contactContent: "",
        nextContactTime: null,
        nextContactPlan: "",
        fileInfo: null
      };

      // 清空文件列表
      this.contactFileList = [];
      this.contactParsedFileList = [];

      this.resetForm("contactForm");
    },
    // 获取当前登录用户信息
    getUserInfo() {
      return this.$store.getters.user || {};
    },
    // 获取联系记录对话框标题
    parseTime(timestamp) {
      if (!timestamp) return '';
      const date = new Date(timestamp);
      return date.toLocaleString();
    },
    /** 快速添加联系记录按钮操作 */
    handleQuickAddContact() {
      // 重置表单并加载客户选项
      this.resetQuickContactForm();
      this.loadCustomerOptions();
      this.quickContactOpen = true;
    },

    /** 加载客户选项 */
    loadCustomerOptions() {
      // 使用已有的客户列表数据
      this.customerOptions = this.casesList.map(item => ({
        caseId: item.caseId,
        customerName: item.customerName,
        contactPhone: item.contactPhone || '无电话'
      }));
    },

    /** 客户选择变更 */
    handleCustomerChange(caseId) {
      this.quickContactForm.caseId = caseId;
    },

    /** 重置快速联系记录表单 */
    resetQuickContactForm() {
      const now = new Date();

      // 设置表单初始值
      this.quickContactForm = {
        caseId: null,
        contactType: "1", // 默认设置为"电话"
        contactPerson: this.getUserInfo().userName || '',
        contactResult: "", // 不设置默认结果
        contactTime: this.parseTime(now, '{y}-{m}-{d} {h}:{i}:{s}'),
        contactContent: "",
        nextContactTime: null,
        nextContactPlan: "",
        fileInfo: null // 重置文件信息
      };

      // 清空文件列表
      this.quickFileList = [];
      this.quickParsedFileList = [];

      this.resetForm("quickContactForm");
    },
    
    /** 处理文件预览 */
    handlePreviewFile(file) {
      console.log('开始预览文件:', file);
      this.currentPreviewFile = file;
      this.previewLoading = true;
      this.imageLoadError = false;
      this.pdfLoadError = false; // 重置PDF错误状态
      this.filePreviewVisible = true;
      
      // 判断文件类型
      const fileName = file.name.toLowerCase();
      this.isImageFile = fileName.endsWith('.jpg') || fileName.endsWith('.png') || 
                        fileName.endsWith('.jpeg') || fileName.endsWith('.gif');
      this.isPdfFile = fileName.endsWith('.pdf');
      
      console.log('文件类型:', {
        fileName: fileName,
        isImageFile: this.isImageFile,
        isPdfFile: this.isPdfFile,
        filePath: file.path
      });

      const baseUrl = process.env.VUE_APP_BASE_API;
      
      // 添加时间戳防止缓存
      const timestamp = new Date().getTime();
      
      // 提取文件路径
      const filePath = file.path;
      
      // 使用客户提供的正确格式URL
      this.previewUrl = `${baseUrl}/system/cases/download-file?filePath=${encodeURIComponent(filePath)}&t=${timestamp}`;
      
      // 备用URL也使用相同格式但增加不同时间戳
      this.backupPreviewUrl = `${baseUrl}/system/cases/download-file?filePath=${encodeURIComponent(filePath)}&t=${timestamp + 1}`;
      
      console.log('构建的预览URL:', this.previewUrl);
      console.log('备用预览URL:', this.backupPreviewUrl);
      
      // 短暂延迟后关闭加载状态
      setTimeout(() => {
        this.previewLoading = false;
      }, 500);
    },
    
    /** 提交快速联系记录表单 */
    submitQuickContactForm() {
      console.log('开始提交快速联系记录表单');
      console.log('快速表单数据:', this.quickContactForm);

      this.$refs["quickContactForm"].validate(valid => {
        console.log('快速表单验证结果:', valid);
        if (valid) {
          // 创建表单数据的副本并格式化日期
          const formData = this.formatDateFields({...this.quickContactForm});
          console.log('格式化后的快速表单数据:', formData);

          // 如果有文件信息，确保包含在表单数据中
          if (this.quickContactForm.fileInfo) {
            formData.fileInfo = this.quickContactForm.fileInfo;
          }

          addContactRecord(formData).then(response => {
            console.log('新增快速联系记录响应:', response);
            if (response.code === 200) {
              this.$modal.msgSuccess("添加联系记录成功");
              this.quickContactOpen = false;

              // 如果当前打开了联系记录对话框并且是相同客户，则刷新列表
              if (this.contactOpen && this.currentCaseId === formData.caseId) {
                this.getContactRecordList();
              }
            } else {
              console.error('新增快速联系记录失败:', response);
              this.$modal.msgError(response.msg || "添加失败");
            }
          }).catch(error => {
            console.error("添加联系记录失败:", error);
            this.$modal.msgError("添加失败，请重试");
          });
        } else {
          console.error('快速表单验证失败');
        }
      });
    },

    /** 取消快速联系记录 */
    cancelQuickContact() {
      this.quickContactOpen = false;
      this.resetQuickContactForm();
    },

    /** 处理下拉命令 */
    handleCommand(command, row) {
      switch (command) {
        case 'update':
          this.handleUpdate(row);
          break;
        case 'delete':
          this.handleDelete(row);
          break;
        case 'contact':
          this.handleContactRecord(row);
          break;
        case 'returnToPool':
          this.handleReturnToPool(row);
          break;
        default:
          break;
      }
    },
    /** 获取联系方式文本 */
    getContactTypeText(value) {
      if (!value) return '';
      const dict = this.dict.type.contact_type;
      if (!dict) return value;

      const found = dict.find(item => item.value === value);
      return found ? found.label : value;
    },

    /** 获取联系结果文本 */
    getContactResultText(value) {
      if (!value) return '';
      const dict = this.dict.type.contact_result;
      if (!dict) return value;

      const found = dict.find(item => item.value === value);
      return found ? found.label : value;
    },
    logContactDialogData() {
      // 如果有文件信息但解析列表为空，尝试手动调用更新函数
      if (this.contactForm.fileInfo && this.contactParsedFileList.length === 0) {
        this.updateContactParsedFileList();
      }
    },
    logQuickContactDialogData() {
      // 快速添加联系记录对话框打开时的处理
    },
    /** 手动设置联系方式字典数据 */
    manuallySetContactTypeDict() {
      console.log('手动设置联系方式字典数据');
      // 创建自定义字典数据
      const contactTypeDict = [
        { dictLabel: '电话', dictValue: '1', cssClass: '', listClass: 'primary' },
        { dictLabel: '短信', dictValue: '2', cssClass: '', listClass: 'success' },
        { dictLabel: '微信', dictValue: '3', cssClass: '', listClass: 'info' },
        { dictLabel: '拜访', dictValue: '4', cssClass: '', listClass: 'warning' },
        { dictLabel: '其他', dictValue: '5', cssClass: '', listClass: 'danger' }
      ];

      // 将数据存入Vuex store
      this.$store.dispatch('dict/setDict', { key: 'contact_type', value: contactTypeDict });

      // 如果dict.type对象已存在，直接设置
      if (this.dict && this.dict.type) {
        // 创建处理后的字典数据（确保格式正确）
        const processedDict = contactTypeDict.map(item => {
          return {
            label: item.dictLabel,
            value: item.dictValue,
            raw: item
          };
        });

        // 设置到组件的dict对象中
        this.$set(this.dict.type, 'contact_type', processedDict);

        // 构建label映射
        processedDict.forEach(item => {
          this.$set(this.dict.label.contact_type, item.value, item.label);
        });
      }
    },

    /** 手动设置联系结果字典数据 */
    manuallySetContactResultDict() {
      console.log('手动设置联系结果字典数据');
      // 创建自定义字典数据
      const contactResultDict = [
        { dictLabel: '已接通', dictValue: '1', cssClass: '', listClass: 'success' },
        { dictLabel: '未接通', dictValue: '2', cssClass: '', listClass: 'warning' },
        { dictLabel: '无效号码', dictValue: '3', cssClass: '', listClass: 'danger' },
        { dictLabel: '拒接', dictValue: '4', cssClass: '', listClass: 'danger' },
        { dictLabel: '无回应', dictValue: '5', cssClass: '', listClass: 'info' },
        { dictLabel: '其他', dictValue: '6', cssClass: '', listClass: 'primary' }
      ];

      // 将数据存入Vuex store
      this.$store.dispatch('dict/setDict', { key: 'contact_result', value: contactResultDict });

      // 如果dict.type对象已存在，直接设置
      if (this.dict && this.dict.type) {
        // 创建处理后的字典数据（确保格式正确）
        const processedDict = contactResultDict.map(item => {
          return {
            label: item.dictLabel,
            value: item.dictValue,
            raw: item
          };
        });

        // 设置到组件的dict对象中
        this.$set(this.dict.type, 'contact_result', processedDict);

        // 构建label映射
        processedDict.forEach(item => {
          this.$set(this.dict.label.contact_result, item.value, item.label);
        });
      }
    },
    /** 处理退回公海 */
    handleReturnToPool(row) {
      // 检查是否有退回公海权限
      if (!this.checkPermission(["system:cases:edit", "system:cases:return-pool"])) {
        this.$message.error("您没有退回公海的权限");
        return;
      }
      
      // 确认对话框
      this.$confirm(`确认将客户"${row.customerName}"退回公海池吗？退回后该客户将不再显示在客户列表中，需要从公海池重新认领。`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 显示加载提示
        const loadingInstance = this.$loading({
          lock: true,
          text: '正在退回公海...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        
        try {
          // 准备请求数据 - 更简化的方式
          const requestData = {
            ids: [row.caseId], // 保持原始ID格式
            poolType: row.poolType || '1',
            updateBy: this.$store.state.user.name,
            isVisible: false // 明确设置为不可见，实现退回公海功能
          };
          
          console.log('退回公海请求数据:', requestData);
          
          // 调用简化API
          updateCasesPool(requestData)
            .then(response => {
              loadingInstance.close();
              console.log('退回公海API响应:', response);
              
              if (response.code === 200) {
                // 操作成功后从列表移除客户
                this.casesList = this.casesList.filter(item => item.caseId !== row.caseId);
                
                // 成功退回公海
                const poolTypeLabel = this.getPoolTypeLabel(requestData.poolType);
                this.$message.success(`已将客户"${row.customerName}"退回${poolTypeLabel}`);
                
                // 更新总数
                this.total = Math.max(0, this.total - 1);
                
                // 无论如何都重新加载数据，确保同步
                this.getList();
              } else {
                // API返回错误
                console.error('退回公海失败:', response);
                this.$message.error(`退回公海失败: ${response.msg || '操作失败'}`);
                
                // 错误时也刷新列表
                this.getList();
              }
            })
            .catch(error => {
              loadingInstance.close();
              console.error('退回公海请求失败:', error);
              
              // 显示错误信息
              let errorMsg = '退回公海失败，请重试';
              if (error.message) {
                errorMsg = `退回公海失败: ${error.message}`;
              }
              this.$message.error(errorMsg);
              
              // 确保列表与服务器同步
              this.getList();
            });
        } catch (e) {
          loadingInstance.close();
          this.$message.error(e.message);
          this.getList();
        }
      }).catch(() => {
        // 用户取消，不做任何处理
      });
    },
    
    /** 获取公海池类型标签 */
    getPoolTypeLabel(poolType) {
      const selectedPool = this.dict.type.pool_type.find(item => item.value === poolType);
      return selectedPool ? selectedPool.label : "公海池";
    },
    
    /** 恢复客户到列表 */
    restoreCustomerToList(customer, index) {
      if (!customer) return;
      
      // 如果有索引信息，插入到原位置
      if (index >= 0 && index < this.casesList.length) {
        this.casesList.splice(index, 0, customer);
      } else {
        // 否则添加到列表末尾
        this.casesList.push(customer);
      }
    },
    
    /** 更新总数计数，不刷新整个列表 */
    updateTotalCount() {
      // 构建一个轻量级查询，只获取总数
      const countQuery = {
        ...this.queryParams,
        pageNum: 1,
        pageSize: 1,
        countOnly: true,  // 特殊标记，告诉后端只需要返回总数
        viewMode: 'customer',
        excludeReturnedToPool: true
      };
      
      // 调用API获取总数
      listBankCustomerCases(countQuery).then(response => {
        if (response.code === 200) {
          // 只更新总数
          this.total = response.total;
        }
      }).catch(error => {
        console.error('获取总数失败:', error);
      });
    },
    
    /** 检查是否有权限 */
    checkPermission(permissions) {
      const all_permission = "*:*:*";
      const userPermissions = this.$store.getters && this.$store.getters.permissions;
      
      if (userPermissions) {
        return userPermissions.some(p => {
          return all_permission === p || permissions.includes(p);
        });
      }
      return false;
    },
    
    /** 提交退回公海 */
    submitReturnToPool() {
      // 防止重复提交
      if (this.submitLoading) {
        return;
      }

      this.$refs.returnToPoolForm.validate(valid => {
        if (valid) {
          // 设置提交状态
          this.submitLoading = true;
          
          // 显示加载提示
          const loadingInstance = this.$loading({
            lock: true,
            text: '正在退回公海...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          });

          const caseId = this.currentCaseToReturn.caseId;
          const ids = Array.isArray(caseId) ? caseId : [caseId];
          
          // 查找选择的公海池对应的标签文本
          const selectedPool = this.dict.type.pool_type.find(item => item.value === this.returnToPoolForm.poolType);
          const poolTypeLabel = selectedPool ? selectedPool.label : this.returnToPoolForm.poolType;
          
          // 确保数据类型正确，将ID转为数值型
          const numericIds = ids.map(id => {
            if (typeof id === 'string') {
              return parseInt(id, 10);
            }
            return id;
          });
          
          // 清空案件负责人和经办人字段，确保退回公海后不再显示在当前列表中
          const data = {
            ids: numericIds,
            poolType: this.returnToPoolForm.poolType,
            caseHandler: null,    // 清空案件负责人
            handlerUser: null,    // 清空经办人
            updateBy: this.$store.state.user.name,
            isVisible: false,     // 明确设置为不可见，实现退回公海功能
            isReturnedToPool: true, // 标记为退回公海操作
            viewMode: 'customer'  // 确保视图模式正确
          };
          
          try {
            // 使用API方法调用而不是直接使用request
            updateCasesPool(data)
              .then(response => {
                this.submitLoading = false;
                loadingInstance.close(); // 关闭加载提示
                
                if (response.code === 200) {
                  this.$modal.msgSuccess(`成功将客户退回到"${poolTypeLabel}"公海池`);
                  this.getList(); // 刷新列表
                  this.returnToPoolDialogVisible = false;
                } else {
                  this.$modal.msgError(response.msg || "退回公海失败");
                }
              })
              .catch(error => {
                this.submitLoading = false;
                loadingInstance.close(); // 关闭加载提示
                
                console.error('退回公海失败:', error);
                // 改进错误处理，显示更具体的错误信息
                let errorMessage = "退回公海失败，请联系管理员";
                if (error && error.message) {
                  errorMessage = `退回公海失败: ${error.message}`;
                }
                this.$modal.msgError(errorMessage);
              });
          } catch (error) {
            this.submitLoading = false;
            loadingInstance.close(); // 关闭加载提示
            
            console.error('执行退回公海操作时发生异常:', error);
            // 改进错误处理，显示更具体的错误信息
            let errorMessage = "退回公海时发生异常，请联系管理员";
            if (error && error.message) {
              errorMessage = `退回公海失败: ${error.message}`;
            }
            this.$modal.msgError(errorMessage);
          }
        }
      });
    },
    
    /** 取消退回公海 */
    cancelReturnToPool() {
      this.returnToPoolDialogVisible = false;
      this.returnToPoolForm.poolType = '';
      this.currentCaseToReturn = null;
      this.submitLoading = false;
    },
    /** 处理分页变化 */
    handlePagination(val) {
      // 保存之前的页大小
      const oldPageSize = this.queryParams.pageSize;
      
      // 更新分页参数
      this.queryParams.pageNum = val.page;
      this.queryParams.pageSize = val.limit;
      
      // 如果页大小变化，重置为第一页
      if (oldPageSize !== val.limit) {
        this.queryParams.pageNum = 1;
      }
      
      // 显示加载进度
      this.loading = true;
      
      // 调用获取列表方法
      this.getList();
      
      // 确保DOM更新后检查分页状态
      this.$nextTick(() => {
        setTimeout(() => this.checkPaginationSync(), 100);
      });
    },
    
    /** 检查分页同步状态 */
    checkPaginationSync() {
      if (document.querySelector('.el-pager li.active')) {
        const activeText = document.querySelector('.el-pager li.active').textContent;
        
        // 如果页码不匹配，尝试修复
        if (parseInt(activeText) !== this.queryParams.pageNum) {
          this.refreshPagination();
        }
      } else {
        this.refreshPagination();
      }
    },
    /**
     * 强制刷新分页组件
     * 用于解决分页组件高亮状态不同步的问题
     */
    refreshPagination() {
      const currentPage = this.queryParams.pageNum;
      
      // 触发视图更新
      this.$nextTick(() => {
        const activePageElement = document.querySelector('.el-pager li.active');
        if (activePageElement) {
          const currentActiveText = activePageElement.textContent;
          
          // 如果状态不同步，尝试修复
          if (parseInt(currentActiveText) !== currentPage) {
            // 使用setTimeout确保UI更新
            setTimeout(() => {
              // 查找对应页码的元素
              const correctPageElement = Array.from(document.querySelectorAll('.el-pager li'))
                .find(el => el.textContent === currentPage.toString());
              
              if (correctPageElement) {
                correctPageElement.click();
              }
            }, 100);
          }
        }
      });
    },
    handleQuickUploadSuccess(response, file, fileList) {
      if (response.code === 200) {
        // 如果是新建客户
        if (!this.quickContactForm.caseId) {
          // 如果已经有文件信息，追加新文件
          if (this.quickContactForm.fileInfo) {
            this.quickContactForm.fileInfo = this.quickContactForm.fileInfo + ';' + response.data;
          } else {
            // 如果还没有文件信息，直接使用新文件
            this.quickContactForm.fileInfo = response.data;
          }
        } else {
          // 如果是修改客户，追加新文件
          const currentFiles = this.quickContactForm.fileInfo ? this.quickContactForm.fileInfo.split(';') : [];
          currentFiles.push(response.data);
          this.quickContactForm.fileInfo = currentFiles.join(';');
        }

        // 更新文件列表显示
        this.quickFileList = fileList;
        this.updateQuickParsedFileList();
        this.$modal.msgSuccess(response.msg);
      } else {
        this.$modal.msgError(response.msg);
      }
    },
    updateQuickParsedFileList() {
      if (!this.quickContactForm.fileInfo) {
        this.quickParsedFileList = [];
        return;
      }

      // 使用通用的文件信息处理函数
      this.quickParsedFileList = this.parseFileInfoToArray(this.quickContactForm.fileInfo);

      // 更新form中的fileInfo，确保没有重复项
      this.quickContactForm.fileInfo = this.convertFileArrayToString(this.quickParsedFileList);
    },
    handleQuickFileDelete(index) {
      this.$modal.confirm('是否确认删除该文件？').then(() => {
        const files = this.quickContactForm.fileInfo.split(';');
        files.splice(index, 1);
        this.quickContactForm.fileInfo = files.join(';');
        this.updateQuickParsedFileList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    handleQuickFileRemove(file, fileList) {
      // 从parsedFileList中找到对应的文件信息
      const removedFile = this.quickParsedFileList.find(f => f.name === file.name);
      if (removedFile) {
        // 从fileInfo中移除该文件
        const files = this.quickContactForm.fileInfo.split(';').filter(f => f !== removedFile.fullInfo);
        this.quickContactForm.fileInfo = files.join(';');
        this.updateQuickParsedFileList();
      }
      this.quickFileList = fileList;
    },
    handleQuickUploadError(error) {
      this.$modal.msgError("上传失败，请重试");
    },
    downloadPreviewFile() {
      if (this.currentPreviewFile) {
        // 使用通用的handleDownload方法下载当前预览的文件
        this.handleDownload(this.currentPreviewFile);
      } else {
        this.$message.warning('无法获取文件信息');
      }
    },
    /**
     * 解析文件信息字符串为数组对象
     * @param {string} fileInfo - 文件信息字符串，格式：文件名|文件路径;文件名|文件路径
     * @returns {Array} 解析后的文件对象数组
     */
    parseFileInfoToArray(fileInfo) {
      if (!fileInfo) return [];
      
      // 过滤空字符串和空白
      const fileInfoArray = fileInfo.split(';').filter(f => f && f.trim() !== '');
      if (fileInfoArray.length === 0) return [];
      
      // 去重
      const uniqueFiles = new Set(fileInfoArray);
      
      return Array.from(uniqueFiles).map(fileInfo => {
        const parts = fileInfo.split('|');
        if (parts.length < 2) {
          return {
            name: parts[0] || '未知文件',
            path: '',
            fullInfo: fileInfo
          };
        }
        return {
          name: parts[0],
          path: parts[1],
          fullInfo: fileInfo
        };
      });
    },
    
    /**
     * 将文件对象数组转换为文件信息字符串
     * @param {Array} fileArray - 文件对象数组
     * @returns {string} 文件信息字符串
     */
    convertFileArrayToString(fileArray) {
      if (!fileArray || !Array.isArray(fileArray) || fileArray.length === 0) return '';
      return fileArray.map(file => file.fullInfo).join(';');
    },
    
    /**
     * 解析文件信息为显示格式
     * @param {string} fileInfo - 文件信息字符串
     * @returns {Array} 文件对象数组
     */
    parseFileInfo(fileInfo) {
      return this.parseFileInfoToArray(fileInfo);
    },
    handleContactUploadSuccess(response, file, fileList) {
      if (response.code === 200) {
        // 如果是新建客户
        if (!this.contactForm.caseId) {
          // 如果已经有文件信息，追加新文件
          if (this.contactForm.fileInfo) {
            this.contactForm.fileInfo = this.contactForm.fileInfo + ';' + response.data;
          } else {
            // 如果还没有文件信息，直接使用新文件
            this.contactForm.fileInfo = response.data;
          }
        } else {
          // 如果是修改客户，追加新文件
          const currentFiles = this.contactForm.fileInfo ? this.contactForm.fileInfo.split(';') : [];
          currentFiles.push(response.data);
          this.contactForm.fileInfo = currentFiles.join(';');
        }

        // 更新文件列表显示
        this.contactFileList = fileList;
        this.updateContactParsedFileList();
        this.$modal.msgSuccess(response.msg);
      } else {
        this.$modal.msgError(response.msg);
      }
    },
    updateContactParsedFileList() {
      if (!this.contactForm.fileInfo) {
        this.contactParsedFileList = [];
        return;
      }

      try {
        // 使用通用的文件信息处理函数
        this.contactParsedFileList = this.parseFileInfoToArray(this.contactForm.fileInfo);
        
        // 更新form中的fileInfo，确保没有重复项
        this.contactForm.fileInfo = this.convertFileArrayToString(this.contactParsedFileList);
      } catch (error) {
        // 出错时保持现有列表
      }
    },
    handleContactFileDelete(index) {
      this.$modal.confirm('是否确认删除该文件？').then(() => {
        const files = this.contactForm.fileInfo.split(';');
        files.splice(index, 1);
        this.contactForm.fileInfo = files.join(';');
        this.updateContactParsedFileList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    handleContactFileRemove(file, fileList) {
      // 从contactParsedFileList中找到对应的文件信息
      const removedFile = this.contactParsedFileList.find(f => f.name === file.name);
      if (removedFile) {
        // 从fileInfo中移除该文件
        const files = this.contactForm.fileInfo.split(';').filter(f => f !== removedFile.fullInfo);
        this.contactForm.fileInfo = files.join(';');
        this.updateContactParsedFileList();
      }
      this.contactFileList = fileList;
    },
    /** 格式化对象中的所有日期字段为正确的格式 */
    formatDateFields(obj) {
      // 定义需要格式化的日期字段
      const dateFields = ['contactTime', 'nextContactTime', 'createTime', 'updateTime'];

      // 遍历所有日期字段
      dateFields.forEach(field => {
        if (obj[field]) {
          // 如果是字符串且包含斜杠，转换格式
          if (typeof obj[field] === 'string') {
            try {
              // 尝试将任何日期格式转换为标准格式
              const date = new Date(obj[field]);
              if (!isNaN(date.getTime())) {
                // 使用yyyy-MM-dd HH:mm:ss格式
                obj[field] = this.formatDate(date);
              }
            } catch (e) {
              console.error(`格式化日期失败: ${field}`, e);
            }
          } else if (obj[field] instanceof Date) {
            // 如果是Date对象，直接格式化
            obj[field] = this.formatDate(obj[field]);
          }
        }
      });

      return obj;
    },

    /** 将日期格式化为yyyy-MM-dd HH:mm:ss格式 */
    formatDate(date) {
      if (!date) return null;

      // 确保是Date对象
      if (!(date instanceof Date)) {
        date = new Date(date);
      }

      // 格式化年月日
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');

      // 格式化时分秒
      const hours = String(date.getHours()).padStart(2, '0');
      const minutes = String(date.getMinutes()).padStart(2, '0');
      const seconds = String(date.getSeconds()).padStart(2, '0');

      // 返回格式化后的字符串
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    },
    handleClosePreview() {
      this.filePreviewVisible = false;
      this.previewUrl = '';
      this.currentPreviewFile = null;
      this.imageLoadError = false;
    },
    /**
     * 处理图片加载错误
     */
    handleImageError() {
      // 尝试备用URL
      if (this.backupPreviewUrl && this.previewUrl !== this.backupPreviewUrl) {
        this.previewUrl = this.backupPreviewUrl;
        this.backupPreviewUrl = null; // 清除备用URL，防止循环尝试
        return; // 不设置错误状态，让新URL尝试加载
      }
      
      // 尝试最终备用URL
      if (this.currentPreviewFile && this.currentPreviewFile.path) {
        const baseUrl = process.env.VUE_APP_BASE_API;
        const timestamp = new Date().getTime() + 100; // 使用新的时间戳
        const finalFallbackUrl = `${baseUrl}/system/cases/download-file?filePath=${encodeURIComponent(this.currentPreviewFile.path)}&t=${timestamp}`;
        this.previewUrl = finalFallbackUrl;
        
        // 避免无限循环
        if (!this._finalAttempt) {
          this._finalAttempt = true;
          return;
        }
      }
      
      // 所有尝试都失败
      this._finalAttempt = false; // 重置尝试标记
      this.imageLoadError = true;
      this.$message.error('图片加载失败，您可以尝试下载查看');
    },

    handleIframeLoad() {
      this.previewLoading = false;
    },
    
    /** 
     * 处理PDF加载错误 
     */
    handleIframeError() {
      this.previewLoading = false;
      this.pdfLoadError = true;
      
      // 尝试备用URL
      if (this.backupPreviewUrl && this.previewUrl !== this.backupPreviewUrl) {
        this.previewUrl = this.backupPreviewUrl;
        this.backupPreviewUrl = null;
        this.pdfLoadError = false; // 重置错误状态继续尝试
        return;
      }
      
      // 尝试最终备用URL
      if (this.currentPreviewFile && this.currentPreviewFile.path) {
        const baseUrl = process.env.VUE_APP_BASE_API;
        const timestamp = new Date().getTime() + 200; // 使用新的时间戳
        const finalFallbackUrl = `${baseUrl}/system/cases/download-file?filePath=${encodeURIComponent(this.currentPreviewFile.path)}&t=${timestamp}`;
        this.previewUrl = finalFallbackUrl;
        this.pdfLoadError = false; // 重置错误状态继续尝试
        
        // 避免无限循环
        if (!this._finalPdfAttempt) {
          this._finalPdfAttempt = true;
          return;
        }
      }
      
      // 所有尝试都失败
      this._finalPdfAttempt = false; // 重置标记
      this.$message.error('PDF加载失败，请尝试下载后查看');
    },
    /**
     * 切换列显示设置面板
     */
    toggleColumnSettings() {
      this.showColumnSettings = !this.showColumnSettings;
      
      // 如果打开了面板，添加点击外部关闭的处理
      if (this.showColumnSettings) {
        this.$nextTick(() => {
          this.addOutsideClickHandler();
        });
      }
    },
    
    /**
     * 添加面板外部点击处理
     */
    addOutsideClickHandler() {
      const handleOutsideClick = (event) => {
        // 获取弹出框和按钮元素
        const popover = document.querySelector('.el-popover');
        const trigger = document.querySelector('[slot="reference"]');
        
        // 如果点击的不是弹出框内部和触发按钮，则关闭弹出框
        if (popover && !popover.contains(event.target) && trigger && !trigger.contains(event.target)) {
          this.showColumnSettings = false;
          // 移除事件监听
          document.removeEventListener('click', handleOutsideClick);
        }
      };
      
      // 延迟添加点击事件，避免当前点击立即触发
      setTimeout(() => {
        document.addEventListener('click', handleOutsideClick);
      }, 0);
    },
    /**
     * 验证手机号码
     * @param {Object} person - 关联人对象
     */
    validatePhone(person) {
      if (!person || !person.phone) return;
      
      const phone = person.phone.trim();
      if (phone && phone !== '') {
        // 只验证长度，不超过11位
        if (phone.length > 11) {
          this.$message.warning('手机号长度不能超过11位');
          
          // 设置错误状态，但不清空输入值
          person.phoneError = true;
        } else {
          // 清除错误状态
          person.phoneError = false;
        }
      } else {
        // 空值不显示错误
        person.phoneError = false;
      }
    },
    /** 检查关联人信息 */
    checkContactPerson(row) {
      // 使用API获取关联人信息
      checkContactPersonInfo(row.caseId).then(response => {
        if (response.code === 200) {
          const data = response.data;
          this.$alert(`
            <div style="text-align:left">
              <p><strong>客户ID:</strong> ${data.caseId}</p>
              <p><strong>客户姓名:</strong> ${data.customerName}</p>
              <p><strong>关联人姓名JSON:</strong> ${data.contactPersonName}</p>
              <p><strong>关联人电话JSON:</strong> ${data.contactPersonPhone}</p>
            </div>
          `, '关联人信息调试', {
            dangerouslyUseHTMLString: true,
            confirmButtonText: '确定'
          });
        } else {
          this.$modal.msgError(response.msg || "获取信息失败");
        }
      }).catch(error => {
        console.error('获取关联人信息失败:', error);
        this.$modal.msgError("获取信息失败: " + (error.message || '未知错误'));
      });
    },
    
    /** 测试提交关联人信息到后端 */
    testSubmitContactPerson(row) {
      // 确保在修改前已经加载了当前客户信息
      if (!row || !row.caseId) {
        this.$message.error('请先选择一个客户');
        return;
      }
      
      // 处理关联人数据
      const contactData = this.cleanContactPersonData();
      
            // 准备提交数据
      const submitData = {
        caseId: row.caseId,
        contactPersonName: JSON.stringify(contactData.names),
        contactPersonPhone: JSON.stringify(contactData.phones),
        contactPersonIdCard: JSON.stringify(contactData.idCards)
      };
      
      // 调用测试API
      testContactPersonInfo(submitData)
        .then(response => {
          if (response.code === 200) {
            this.$message.success('测试提交成功：' + response.msg);
            // 刷新数据
            this.handleUpdate(row);
          } else {
            this.$message.error('测试提交失败：' + response.msg);
          }
        })
        .catch(error => {
          this.$message.error('测试提交失败: ' + (error.message || '未知错误'));
        });
    },
    /** 更新关联人信息 */
    updateContactPersons(row) {
      if (!row || !row.caseId) {
        this.$message.error('客户ID不能为空');
        return;
      }

      // 验证关联人信息
      if (!this.validateContactPersons()) {
        return;
      }

      // 处理关联人数据
      const contactData = this.cleanContactPersonData();
      
      // 准备提交数据
      const submitData = {
        caseId: row.caseId,
        contactPersonName: JSON.stringify(contactData.names),
        contactPersonPhone: JSON.stringify(contactData.phones),
        contactPersonIdCard: JSON.stringify(contactData.idCards)
      };
      
      // 显示加载状态
      const loading = this.$loading({
        lock: true,
        text: '正在更新关联人信息...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      
      // 调用API更新关联人信息
      updateContactPersons(submitData)
        .then(response => {
          loading.close();
          if (response.code === 200) {
            this.$message.success('关联人信息更新成功');
            // 刷新列表
            this.getList();
          } else {
            this.$message.error('关联人信息更新失败：' + response.msg);
          }
        })
        .catch(error => {
          loading.close();
          this.$message.error('关联人信息更新失败：' + error.message);
        });
    },
    
    /**
     * 验证身份证号码
     * @param {Object} person - 关联人对象
     */
    validateIdCard(person) {
      if (!person || !person.idCard) return;
      
      const idCard = person.idCard.trim();
      if (idCard && idCard !== '') {
        // 只验证长度，不检查格式
        if (idCard.length > 18) {
          this.$message.warning('身份证号码长度不能超过18位');
          
          // 设置错误状态，但不清空输入值
          person.idCardError = true;
        } else {
          // 清除错误状态
          person.idCardError = false;
        }
      } else {
        // 空值不显示错误
        person.idCardError = false;
      }
    },
    
    /**
     * 删除关联人
     * @param {Number} index - 要删除的关联人索引
     */
    removeContactPerson(index) {
      try {
        // 验证参数有效性
        if (!this.isValidContactPersonIndex(index)) return;
        
        // 使用不可变方式更新数组
        this.updateContactPersonsArray(oldArray => {
          const newArray = [...oldArray];
          newArray.splice(index, 1);
          return newArray;
        });
        
        // 如有必要，同步到服务器
        this.syncContactPersonsToServer();
      } catch (error) {
        this.$message.error('删除关联人失败');
      }
    },
    
    /**
     * 验证关联人索引是否有效
     * @param {Number} index - 索引值
     * @returns {Boolean} 是否有效
     */
    isValidContactPersonIndex(index) {
      return this.contactPersons && 
             Array.isArray(this.contactPersons) && 
             index >= 0 && 
             index < this.contactPersons.length;
    },
    
    /**
     * 更新关联人数组
     * @param {Function} updateFn - 更新函数，接收旧数组返回新数组
     */
    updateContactPersonsArray(updateFn) {
      this.contactPersons = updateFn(this.contactPersons);
      this.contactPersonsKey++; // 强制表格重新渲染
      this.$forceUpdate();
    },
    
    /**
     * 如果需要，同步关联人数据到服务器
     */
    syncContactPersonsToServer() {
      if (this.form.caseId) {
        this.updateContactPersonsData();
      }
    },
    
    /**
     * 更新关联人数据到后端
     * @returns {Promise} 更新操作的Promise
     */
    updateContactPersonsData() {
      try {
        // 检查必要参数
        if (!this.form.caseId) {
          return Promise.reject(new Error('客户ID不能为空'));
        }
        
        // 处理关联人数据
        const contactData = this.cleanContactPersonData();
        
        // 准备提交数据
        const submitData = this.prepareContactPersonsSubmitData(contactData);
        
        // 调用API更新关联人信息
        return updateContactPersons(submitData)
          .then(response => {
            if (response.code !== 200) {
              this.$message.error('关联人信息更新失败');
              return Promise.reject(new Error(response.msg));
            }
            return response;
          })
          .catch(error => {
            this.$message.error('更新关联人信息失败');
            return Promise.reject(error);
          });
      } catch (error) {
        this.$message.error('更新关联人信息失败');
        return Promise.reject(error);
      }
    },
    
    /**
     * 准备关联人提交数据
     * @param {Object} contactData - 清理后的关联人数据
     * @returns {Object} 提交数据对象
     */
    prepareContactPersonsSubmitData(contactData) {
      return {
        caseId: this.form.caseId,
        contactPersonName: JSON.stringify(contactData.names || []),
        contactPersonPhone: JSON.stringify(contactData.phones || []),
        contactPersonIdCard: JSON.stringify(contactData.idCards || [])
      };
    },

    /** 获取文件图标类名 */
    getFileIcon(fileName) {
      if (!fileName) return 'el-icon-document';
      
      const lowerFileName = fileName.toLowerCase();
      
      if (lowerFileName.endsWith('.pdf')) {
        return 'el-icon-document pdf-icon';
      } else if (lowerFileName.endsWith('.doc') || lowerFileName.endsWith('.docx')) {
        return 'el-icon-document word-icon';
      } else if (lowerFileName.endsWith('.jpg') || lowerFileName.endsWith('.jpeg') || 
                lowerFileName.endsWith('.png') || lowerFileName.endsWith('.gif')) {
        return 'el-icon-picture-outline image-icon';
      } else if (lowerFileName.endsWith('.xls') || lowerFileName.endsWith('.xlsx')) {
        return 'el-icon-document excel-icon';
      } else if (lowerFileName.endsWith('.ppt') || lowerFileName.endsWith('.pptx')) {
        return 'el-icon-document ppt-icon';
      } else if (lowerFileName.endsWith('.zip') || lowerFileName.endsWith('.rar') || lowerFileName.endsWith('.7z')) {
        return 'el-icon-folder zip-icon';
      } else if (lowerFileName.endsWith('.txt')) {
        return 'el-icon-document txt-icon';
      } else {
        return 'el-icon-document';
      }
    },

  }
};
</script>

<style scoped>
.upload-demo {
  margin-bottom: 10px;
}
.el-upload__tip {
  line-height: 1.2;
  color: #909399;
  font-size: 12px;
}
.file-grid-container {
  display: flex;
  flex-wrap: wrap;
  margin-top: 15px;
  gap: 15px;
}
.file-grid-item {
  width: 120px;
  height: 150px;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
  position: relative;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
  will-change: transform, box-shadow;
}
.file-grid-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transform: translateY(-1px);
}
.file-icon {
  font-size: 50px;
  margin-bottom: 10px;
  color: #409EFF;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60px;
}
.file-icon i.el-icon-document {
  color: #67C23A;
}
.file-icon i.pdf-icon {
  color: #F56C6C;
}
.file-icon i.excel-icon {
  color: #67C23A;
}
.file-icon i.ppt-icon {
  color: #E6A23C;
}
.file-icon i.txt-icon {
  color: #909399;
}
.file-icon i.zip-icon {
  color: #909399;
}
.file-icon i.word-icon {
  color: #409EFF;
}
.file-icon i.image-icon {
  color: #E6A23C;
}
.file-info {
  width: 100%;
  text-align: center;
}
.file-name-ellipsis {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  margin-bottom: 8px;
}
.file-actions {
  display: flex;
  justify-content: center;
  width: 100%;
  margin-top: auto;
}
.file-actions .el-button {
  padding: 5px;
  font-size: 16px;
}
.file-actions .el-button+.el-button {
  margin-left: 10px;
}

/* 表格样式优化 */
.app-container {
  position: absolute;
  top: 50px; /* 减小顶部位置，避免顶部白条 */
  left: 0;
  right: 0;
  bottom: 0;
  padding: 0 5px 0 5px; /* 移除底部内边距 */
  margin-top: -50px; /* 使用负边距向上移动整个容器 */
  background-color: #ffffff;
  overflow-x: hidden;
  overflow-y: hidden;
  box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.05);
  border-radius: 4px 4px 0 0;
  display: flex;
  flex-direction: column;
  z-index: 100;
  margin-left: 0;
  margin-right: 0;
  margin-bottom: 0;
  border: none;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  -webkit-font-smoothing: antialiased;
}

/* 搜索区域优化 */
.el-form.compact-form {
  background-color: #ffffff;
  padding: 0px 5px 0px;
  margin-bottom: 2px;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(255, 255, 255, 0.05);
}

/* 操作按钮区域 */
.mb8, .compact-mb {
  margin-bottom: 2px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.mb8 .el-button, .compact-mb .el-button {
  margin-bottom: 2px;
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out, background-color 0.15s ease-out;
  padding: 5px 10px;
  will-change: transform;
}

.mb8 .el-button:hover, .compact-mb .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
  transition: transform 0.15s ease-out, box-shadow 0.15s ease-out;
}

/* 表格内容滚动，表头固定 ，表格文字大小*/
.el-table {
  margin-top: 0px;
  margin-bottom: 2px;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
  flex: 1;
  font-size: 16px; /* 增加表格整体文本大小 */
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}

.el-table::before {
  height: 0; /* 移除表格底部边框 */
}

.el-table__header-wrapper {
  overflow: hidden;
}

.el-table__body-wrapper {
  overflow-y: auto !important;
}

.el-table th {
  background: #ffffff !important;
  font-weight: 600;
  color: #303133;
  height: 20px;
  border-bottom: 1px solid #ebeef5;
  padding: 2px 0;
  font-size: 15px; /* 增加表头文本大小 */
}

.el-table td {
  padding: 1px 0;
  height: 28px;
  font-size: 14px; /* 确保表格内容文本大小一致 */
}

.el-table--striped .el-table__body tr.el-table__row--striped td {
  background: #ffffff;
}

.el-table--enable-row-hover .el-table__body tr:hover>td {
  background-color: #f5f7fa;
}

/* 分页器样式优化 */
.pagination-container {
  padding: 3px 0;
  background: #ffffff;
  margin-top: 2px;
  display: flex;
  justify-content: flex-end;
  border-top: 1px solid rgb(255, 255, 255);
}

/* 确保分页器数字高亮正常显示 */
::v-deep .el-pagination.is-background .el-pager li.active {
  background-color: #409EFF !important;
  color: #fff !important;
  font-weight: bold !important;
}

::v-deep .el-pagination.is-background .el-pager li:not(.disabled).active {
  background-color: #409EFF !important;
  color: #fff !important;
  font-weight: bold !important;
}

::v-deep .el-pagination.is-background .btn-next, 
::v-deep .el-pagination.is-background .btn-prev, 
::v-deep .el-pagination.is-background .el-pager li {
  min-width: 32px;
  border-radius: 2px;
  font-weight: normal;
  margin: 0 4px;
}

/* 表格内按钮样式优化 */
.el-table .cell .el-button--text {
  padding: 2px 0;
  font-size: 13px; /* 增加表格内按钮文本大小 */
  transition: color 0.15s ease-out;
}

.el-table .cell .el-button--text+.el-button--text {
  margin-left: 8px;
}

.el-table .cell .el-button--text:hover {
  color: #409EFF;
  background: transparent;
}

/* 修改对话框样式 */
::v-deep .el-dialog {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

::v-deep .el-dialog__header {
  background: #ffff;
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
}

::v-deep .el-dialog__title {
  font-weight: 700;
  font-size: 18px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

::v-deep .el-dialog__body {
  padding: 20px 25px;
}

::v-deep .el-dialog__footer {
  padding: 15px 20px;
  border-top: 1px solid #ebeef5;
  background: #ffffff;
}

::v-deep .el-form-item__label {
  font-size: 15px;
  font-weight: 700;
  color: #303133;
}

/* 对话框中输入框字体样式 */
::v-deep .el-dialog .el-input__inner,
::v-deep .el-dialog .el-textarea__inner,
::v-deep .el-dialog .el-select .el-input__inner {
  font-size: 15px;
  color: #303133;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
}

/* 表单项样式统一设置 */
::v-deep .el-dialog .el-form-item__content,
::v-deep .el-dialog .el-form-item__label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: left;
}

/* 表单项内容额外设置 */
::v-deep .el-dialog .el-form-item__content {
  display: flex;
}

/* 对话框表单整体左对齐 */
::v-deep .el-dialog .el-form {
  text-align: left;
}

/* 下拉选项字体样式 */
::v-deep .el-select-dropdown__item {
  font-size: 15px;
  color: #303133;
  text-align: left;
}

/* 选中的下拉选项和按钮字体样式 */
::v-deep .el-select-dropdown__item.selected {
  font-weight: 600;
  color: #409EFF;
}

/* 对话框按钮字体样式 */
::v-deep .el-dialog .el-button {
  font-size: 15px;
  font-weight: 500;
}

/* 简化的关联人信息表格样式 */
.contact-persons-simple {
  line-height: 1.4;
  word-break: break-all;
  color: #606266;
  padding: 0 5px;
}

.contact-person-item-simple {
  font-size: 12px;
}

/* 简化的关联人信息编辑器样式 */
.contact-persons-editor-simple {
  border-top: 1px solid #f0f0f0;
  padding-top: 10px;
}

.contact-person-row {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.add-contact-simple {
  margin-top: 5px;
  text-align: left;
  border-top: 1px dashed #f0f0f0;
  padding-top: 8px;
}

.contact-record-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.contact-record-list {
  flex: 1;
  overflow: auto;
}

.contact-person-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.add-contact-simple {
  margin-top: 8px;
}

.existing-files {
  margin-top: 10px;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 0;
  border-bottom: 1px solid #eee;
}

.file-actions {
  display: flex;
}

.el-dropdown-menu__item {
  display: flex;
  align-items: center;
  padding: 8px 16px;
}

.el-dropdown-menu__item i {
  margin-right: 8px;
  font-size: 16px;
}

.action-more-btn {
  padding: 6px;
  border-radius: 50%;
  transition: all 0.3s;
}

.action-more-btn:hover {
  background-color: #f2f6fc;
  color: #409EFF;
}

.action-more-btn i {
  font-size: 18px;
}

.text-primary {
  color: #409EFF;
}

.text-danger {
  color: #F56C6C;
}

.text-info {
  color: #909399;
}

::v-deep .el-table .cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-dialog {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.8);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.preview-container {
  background-color: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
  width: 100%;
  height: 80vh;
  overflow: auto;
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-preview-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.preview-image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}

.preview-iframe {
  width: 100%;
  height: 75vh;
  border: none;
}

.no-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  height: 100%;
}

.no-preview i {
  font-size: 48px;
  margin-bottom: 10px;
}

.no-preview p {
  font-size: 16px;
  text-align: center;
}

.download-button {
  margin-top: 20px;
}

.image-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #F56C6C;
  font-size: 16px;
  margin-top: 20px;
  padding: 30px;
  background-color: #fef0f0;
  border-radius: 4px;
  width: 100%;
  max-width: 400px;
}

.image-error i {
  font-size: 48px;
  margin-bottom: 15px;
}

.image-error p {
  margin-bottom: 20px;
  font-size: 16px;
  text-align: center;
  color: #606266;
}

.image-toolbar {
  position: absolute;
  bottom: 20px;
  right: 20px;
  background-color: rgba(0, 0, 0, 0.5);
  padding: 8px;
  border-radius: 4px;
  z-index: 10;
}

.image-toolbar .el-button {
  color: white;
  border-color: transparent;
  background-color: transparent;
}

.image-toolbar .el-button:hover {
  background-color: rgba(255, 255, 255, 0.2);
}

.pdf-preview-wrapper {
  width: 100%;
  height: 75vh;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.pdf-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #F56C6C;
  font-size: 16px;
  margin-top: 20px;
  padding: 30px;
  background-color: #fef0f0;
  border-radius: 4px;
  width: 100%;
  max-width: 400px;
}

.pdf-error i {
  font-size: 48px;
  margin-bottom: 15px;
}

.pdf-error p {
  margin-bottom: 20px;
  font-size: 16px;
  text-align: center;
  color: #606266;
}

::v-deep .el-popover {
  max-height: 300px;
  overflow-y: auto;
  padding: 15px;
}

::v-deep .el-popover .el-checkbox-group {
  display: flex;
  flex-direction: column;
}

::v-deep .el-popover .el-checkbox {
  margin-left: 0;
  margin-bottom: 8px;
  height: auto;
  padding: 5px 0;
}

::v-deep .el-popover .el-checkbox+.el-checkbox {
  margin-left: 0;
}

.contact-tip {
  font-size: 12px;
  color: #909399;
  line-height: 1.4;
  margin-top: 5px;
  padding-left: 5px;
}

.contact-persons-container {
  margin: 0;
  padding: 0;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  background-color: #fff;
  transition: all 0.3s ease;
}

.contact-persons-container:hover {
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}

.contact-persons-table {
  width: 100%;
  margin-bottom: 10px;
  border: 1px solid #EBEEF5;
  border-radius: 4px;
}

.contact-persons-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 15px;
  margin-top: 8px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e8eaec;
  transition: background-color 0.3s ease;
}

.contact-persons-footer:hover {
  background-color: #eef1f6;
}

.contact-persons-actions {
  display: flex;
  gap: 10px;
}

.contact-tip {
  color: #909399;
  font-size: 12px;
  display: flex;
  align-items: center;
  padding-right: 10px;
  line-height: 1.5;
  background-color: rgba(64, 158, 255, 0.08);
  border-radius: 4px;
  padding: 6px 12px;
}

.contact-tip i {
  margin-right: 8px;
  color: #409EFF;
  font-size: 14px;
}

/* 表格内的输入框占满整个单元格 */
::v-deep .contact-persons-table .el-input {
  width: 100%;
}

/* 减小表格内部的内边距 */
::v-deep .contact-persons-table .el-table__cell {
  padding: 8px !important;
}

/* 表格行高度适中 */
::v-deep .contact-persons-table .el-table__row {
  height: 45px;
  transition: background-color 0.2s ease;
}

::v-deep .contact-persons-table .el-table__row:hover {
  background-color: #f0f7ff !important;
}

/* 删除按钮颜色 */
::v-deep .contact-persons-table .delete-contact-btn {
  color: #F56C6C;
  transition: all 0.3s ease;
  font-size: 13px;
  opacity: 0.85;
}

::v-deep .contact-persons-table .delete-contact-btn:hover {
  color: #ff4d4f;
  opacity: 1;
  transform: scale(1.05);
}

/* 输入框验证不通过时的样式 */
::v-deep .contact-persons-table .is-error .el-input__inner {
  border-color: #F56C6C;
  background-color: rgba(245, 108, 108, 0.05);
}

.error-tip {
  color: #F56C6C;
  font-size: 12px;
  margin-top: 5px;
  line-height: 1.4;
  display: flex;
  align-items: center;
  padding: 4px 8px;
  background-color: #fff1f0;
  border-radius: 2px;
  animation: errorFadeIn 0.3s ease;
}

.error-tip i {
  margin-right: 4px;
}

@keyframes errorFadeIn {
  from {
    opacity: 0;
    transform: translateY(-5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 美化表格头部 */
::v-deep .contact-persons-table .el-table__header th {
  background-color: #f5f7fa !important;
  color: #606266;
  font-weight: bold;
  padding: 10px 0;
  letter-spacing: 0.5px;
}

/* 美化输入框 */
::v-deep .contact-persons-table .el-input__inner {
  transition: all 0.3s;
  border-radius: 4px;
  padding-left: 30px;
  height: 32px;
  border: 1px solid #dcdfe6;
}

::v-deep .contact-persons-table .el-input__inner:focus {
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

::v-deep .contact-persons-table .el-input__prefix {
  left: 8px;
  color: #c0c4cc;
}

::v-deep .contact-persons-table .el-input:hover .el-input__inner {
  border-color: #c0c4cc;
}

/* 美化按钮 */
.add-contact-btn {
  transition: all 0.3s ease;
  border-radius: 4px;
  padding: 8px 15px;
  font-weight: 500;
}

.add-contact-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.25);
  background-color: #409EFF;
  color: white;
}

.no-contacts-tip {
  color: #909399;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border: 1px dashed #dcdfe6;
}

.no-contacts-tip i {
  margin-right: 8px;
  font-size: 20px;
  color: #409EFF;
}

.no-contacts-tip i {
  margin-right: 5px;
  color: #409EFF;
}

.contact-persons-footer .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.no-contacts-tip {
  text-align: center;
  padding: 20px 0;
  color: #909399;
  background-color: #f9f9f9;
  border: 1px dashed #e0e0e0;
  border-radius: 4px;
  margin-bottom: 10px;
}

.no-contacts-tip i {
  margin-right: 5px;
  font-size: 16px;
  color: #409EFF;
}

/* 分组标题样式 */
.section-header {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.section-header i {
  font-size: 18px;
  color: #409EFF;
  margin-right: 8px;
}

.section-header span {
  font-size: 15px;
  font-weight: 600;
  color: #303133;
}

/* 关联人信息区域样式 */
.contact-persons-container {
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
  padding-bottom: 5px;
}

.contact-persons-table {
  width: 100%;
  margin-bottom: 10px;
}

.contact-persons-table .el-table__header th {
  background-color: #f5f7fa !important;
  color: #606266;
  font-weight: 600;
  height: 40px;
  line-height: 40px;
  padding: 0;
}

.contact-persons-table .el-table__row {
  height: 45px;
}

.contact-persons-table .el-table__row:hover {
  background-color: #f0f7ff;
}

/* 统一输入框样式 */
.uniform-input {
  width: 100%;
}

.uniform-input .el-input__inner {
  height: 32px;
  line-height: 32px;
  padding-left: 30px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  transition: all 0.2s;
}

.uniform-input .el-input__inner:focus {
  border-color: #409EFF;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.uniform-input .el-input__prefix {
  left: 8px;
  color: #c0c4cc;
}

/* 错误提示样式 */
.error-tip {
  color: #F56C6C;
  font-size: 12px;
  margin-top: 5px;
  padding: 2px 5px;
  display: flex;
  align-items: center;
  animation: fadeIn 0.3s ease;
  background-color: rgba(245, 108, 108, 0.1);
  border-radius: 2px;
}

.error-tip i {
  margin-right: 5px;
  font-size: 14px;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 关联人底部区域样式 */
.contact-persons-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  margin-top: 5px;
  background-color: #f8f9fa;
  border-top: 1px solid #ebeef5;
  border-radius: 0 0 4px 4px;
}

.contact-persons-actions {
  display: flex;
}

.add-contact-btn {
  padding: 8px 16px;
  transition: all 0.3s;
  font-weight: 500;
  border-radius: 4px;
  border: 1px solid #c6e2ff;
  background-color: rgba(64, 158, 255, 0.1);
}

.add-contact-btn:hover {
  background-color: #409EFF;
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
}

.contact-tip {
  color: #909399;
  font-size: 12px;
  display: flex;
  align-items: center;
  padding: 5px 10px;
  background-color: rgba(64, 158, 255, 0.08);
  border-radius: 3px;
}

.contact-tip i {
  color: #409EFF;
  margin-right: 5px;
  font-size: 14px;
}

/* 删除按钮样式 */
.delete-contact-btn {
  color: #F56C6C;
  transition: all 0.2s;
  opacity: 0.8;
}

.delete-contact-btn:hover {
  color: #F56C6C;
  opacity: 1;
  transform: scale(1.1);
}

/* 无关联人提示样式 */
.no-contacts-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 120px;
  background-color: #f8f9fa;
  color: #909399;
  font-size: 14px;
  border-radius: 4px;
  margin-bottom: 5px;
  border: 1px dashed #e0e0e0;
  transition: all 0.3s ease;
}

.no-contacts-tip:hover {
  background-color: #f0f7ff;
  border-color: #c6e2ff;
}

.no-contacts-tip i {
  color: #409EFF;
  margin-right: 12px;
  font-size: 24px;
}

.no-contacts-text {
  display: flex;
  flex-direction: column;
}

.no-contacts-text p {
  margin: 0;
  line-height: 1.6;
}

.sub-tip {
  font-size: 12px;
  color: #c0c4cc;
}

/* 有错误时的输入框样式 */
.is-error .el-input__inner {
  border-color: #F56C6C !important;
  background-color: rgba(245, 108, 108, 0.05);
}

/* 自适应对话框样式 */
.adaptive-dialog {
  display: flex;
  flex-direction: column;
  position: relative;
}

/* 修复el-dialog__wrapper的居中问题 */
body .el-dialog__wrapper.horizontal-center {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

/* 对话框过渡动画 */
.adaptive-dialog /deep/ .el-dialog {
  transform: none;
  transition: all 0.3s ease-in-out;
}

/* 对话框进入动画 */
.el-dialog__wrapper {
  transition: opacity 0.3s ease-in-out;
}

.el-dialog__wrapper.dialog-fade-enter-active,
.el-dialog__wrapper.dialog-fade-leave-active {
  opacity: 0;
}

.el-dialog__wrapper.dialog-fade-enter-active .el-dialog,
.el-dialog__wrapper.dialog-fade-leave-active .el-dialog {
  transform: translateY(-30px);
}

/* 对话框标题栏样式 */
.adaptive-dialog /deep/ .el-dialog {
  margin: 5vh auto !important;
  border-radius: 8px;
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  max-height: 90vh; /* 最大高度为视口高度的90% */
}

/* 水平居中样式 */
.horizontal-center /deep/ .el-dialog {
  position: relative;
  left: 0;
  right: 0;
  margin-left: auto !important;
  margin-right: auto !important;
  transform: translateX(0) !important;
}

/* 修复对话框容器样式 */
.horizontal-center.el-dialog__wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* 标题栏样式 */
.adaptive-dialog /deep/ .el-dialog__header {
  background-color: #f8f9fa;
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
  margin: 0;
  text-align: left;
}

.adaptive-dialog /deep/ .el-dialog__title {
  font-weight: 600;
  font-size: 16px;
  color: #303133;
  text-align: left;
}

/* 内容区域样式 */
.adaptive-dialog /deep/ .el-dialog__body {
  overflow-y: auto;
  padding: 20px;
  /* 设置最小高度和最大高度 */
  min-height: 200px;
  max-height: calc(90vh - 120px); /* 减去头部和底部的高度 */
  white-space: normal; /* 确保对话框内容可以正常换行 */
}

/* 底部按钮区域样式 */
.adaptive-dialog /deep/ .el-dialog__footer {
  background-color: #f8f9fa;
  border-top: 1px solid #ebeef5;
  padding: 15px 20px;
  text-align: right;
}

/* 表单滚动区域样式 */
.scrollable-form {
  overflow-y: auto;
  padding-right: 10px;
  height: 100%;
  max-height: calc(90vh - 150px);
}

/* 自定义滚动条样式 */
.scrollable-form::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.scrollable-form::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 3px;
}

.scrollable-form::-webkit-scrollbar-track {
  background: #f0f2f5;
  border-radius: 3px;
}

.adaptive-dialog /deep/ .el-dialog__body::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.adaptive-dialog /deep/ .el-dialog__body::-webkit-scrollbar-thumb {
  background: #c0c4cc;
  border-radius: 3px;
}

.adaptive-dialog /deep/ .el-dialog__body::-webkit-scrollbar-track {
  background: #f0f2f5;
  border-radius: 3px;
}

/* 对话框关闭按钮样式 */
.adaptive-dialog /deep/ .el-dialog__headerbtn {
  top: 15px;
  right: 15px;
}

.adaptive-dialog /deep/ .el-dialog__headerbtn:hover .el-dialog__close {
  color: #409EFF;
}

/* 居右按钮区域 */
.dialog-footer {
  text-align: right;
  margin-top: 20px;
}

.dialog-footer .el-button {
  min-width: 100px;
  padding: 10px 20px;
}

/* 响应式布局调整 - 保持固定宽度 */
@media screen and (max-width: 768px) {
  .adaptive-dialog /deep/ .el-dialog {
    width: 900px !important; /* 保持固定宽度 */
    max-width: 95vw; /* 防止超出屏幕 */
  }
  
  .adaptive-dialog /deep/ .el-dialog__body {
    padding: 15px 10px;
  }
  
  .el-form-item__label {
    width: 80px !important;
  }
  
  .el-form-item__content {
    margin-left: 80px !important;
  }
}

.contact-persons-container-simple {
  border: 1px solid #EBEEF5;
  border-radius: 4px;
  padding: 10px;
  background-color: #fff;
}

.contact-persons-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.contact-person-item {
  display: flex;
  gap: 8px;
  align-items: center;
}

.contact-input {
  width: 33%;
}

.contact-delete-btn {
  color: #F56C6C;
  padding: 0;
  margin-left: 5px;
}

.contact-persons-footer-simple {
  margin-top: 10px;
  text-align: left;
}

.add-contact-btn-simple {
  color: #409EFF;
}

.section-header-compact {
  margin-bottom: 5px;
  padding-bottom: 5px;
  border-bottom: 1px solid #ebeef5;
}

/** 下拉框字体*/
.section-header-compact span {
  font-size: 16px;
  font-weight: 700;
  color: #303133;
}

.contact-persons-container-compact {
  border: 1px solid #EBEEF5;
  border-radius: 2px;
  padding: 5px;
  background-color: #fff;
}

.contact-persons-list-compact {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.contact-person-item-compact {
  display: flex;
  gap: 5px;
  align-items: center;
}

.contact-input-compact {
  width: 33%;
}

.contact-delete-btn-compact {
  color: #F56C6C;
  padding: 0;
  margin-left: 3px;
}

.contact-add-btn-wrapper {
  margin-top: 5px;
}

.add-contact-btn-compact {
  color: #409EFF;
  padding: 0;
  font-size: 12px;
}
</style>
